3

I'm using Spring's DelegatingFilterProxy to use a Spring bean as a container filter. In order to use the init and destroy methods from the Filter interface I'm defining targetFilterLifecycle as true.

Does Spring ensure all the dependency injected beans in the filter class are available by the time the container calls the init method or is there a risk that some beans are still not initialized or at least injected?

Also, what was the reasoning behind Spring setting the targetFilterLifecycle default as false?

andresp
  • 1,624
  • 19
  • 31

2 Answers2

2

Spring framework always ensure that beans are initialized before being used and filters it manages are not an exception.

Normal filters initialize themselves via init (and destroy) method, but Spring beans can be initialized by dependency injection. That's the reason why by default Spring supposes they are simply initialized as beans and do not rely on init method.

Edd
  • 3,724
  • 3
  • 26
  • 33
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Can you elaborate how spring ensures it? I asked similar question https://stackoverflow.com/questions/47434743/get-spring-boot-bean-from-jersey-non-spring-context – Ori Marko Nov 27 '17 at 06:32
2

Spring loads its application context through the ContextLoaderListener which is a ServletContextListener (part of the Servlet API). All registered ServletContextListener and other listener types are initialized before any declared Filters and Servlets.

As such, and assuming you set targetFilterLifecycle to false, by the time your DelegatingFilterProxy is created by the Servlet container, your Filter bean is already created and initialized inside the application context (that's where it should be declared).

The javadoc states the following about targetFilterLifecycle:

Default is "false"; target beans usually rely on the Spring application context for managing their lifecycle. Setting this flag to "true" means that the servlet container will control the lifecycle of the target Filter, with this proxy delegating the corresponding calls.

If you set it or leave it as false, Spring will be responsible for initializing the object and doing any bean injection (and/or performing other lifecycle steps). If you set it to true, Spring will give it to the Servlet container to do its own initialization after having done its own. This is done by invoking the init method at startup and the destroy method when shutting down.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thanks. I suppose that in the second case "Spring will give it to the Servlet container to do its own initialization" always after doing its own initialization (dependency injection et al) first then. – andresp Jun 09 '14 at 15:53
  • @andresp Actually, it probably will. It will additionally do the servlet initialization steps. – Sotirios Delimanolis Jun 09 '14 at 15:55
  • That's my doubt here. If I set it to true, will the Spring injected beans be already loaded too? From what I see in your answer (Application Context being initialized before the Container filters) I would expect so. EDIT: OK, thanks! – andresp Jun 09 '14 at 15:56
  • @andresp Yes, it will be initialized. The `DelegatingFilterProxy` will retrieve the initialized bean, check `targetFilterLifecycle`, and call the `init` method if it is `true`. – Sotirios Delimanolis Jun 09 '14 at 15:57