Spring - why initialization is called after setter method - spring

Just curious.
Why bean initialization is done after setter's method? I thought initialization is best done before setter method - like doing validation to ensure it's good prior to setting the value to the instance member
Why beanPostProcessor considered a after initialization when it has a beforeInitialization method?

From my understanding, calls of setters etc is considered to be the action to setup the initial state of the bean. You cannot do any meaningful initialization without the initial state of the bean set. Just think what will happen if initialization is done before setters: (assume we are using setter injection, not ctor injection) The bean is created by calling the default ctor, and then you call the initialization, what can you initialize then? The bean is simply a blank object without dependencies properly injected. If you can do initialization in such case, such kind of initialization can be simply put in your ctor.
For BeanPostProcessor, I believe the "post" is not referring to post-initialize. It is simply for you to do post processing after the bean is created (i.e. post-creation). As it is common to do such kind of post processing in two different timing, which is before and after the bean is initialized. Hence for the two methods.

So initialization can use the values set on the bean.
Because it's a post-processor.

Related

Where does the dependency injection take place?

As far as i know:
BeanFactory creates beans according to its definitions.
Then sends it to BeanPostProcessor to invoke postProcessBeforeInitialization().
Receives it back and provides init() method.
BeanPostProcessor with postProcessAfterInitialization() method.
Bean finally configured and sent into IoC container.
My question is: "At what stage does dependency injection take place?".
Really curious on how it works under the hood.
Dependency injection typically takes place during the initialization of a bean, after the bean has been instantiated by the BeanFactory, but before the bean is fully initialized and ready to be used by the application.
The process typically works as follows:
The BeanFactory creates an instance of the bean according to its definitions.
The BeanPostProcessor's postProcessBeforeInitialization() method is invoked, which allows for any pre-initialization processing to take place, such as setting up some initial values or performing some other setup tasks.
The BeanFactory then proceeds to set the bean's properties and dependencies, using either setter injection or constructor injection, which are the two most common forms of dependency injection. This step is where the actual injection of dependencies takes place.
The BeanPostProcessor's postProcessAfterInitialization() method is invoked, which allows for any post-initialization processing to take place, such as performing some validation or other tasks on the fully initialized bean.
The Bean is finally configured and sent into IoC container.
It's important to note that the step 2 and 4 are optional, and not all BeanPostProcessor implementation will invoke them.
BeanPostProcessor is an interface that allows for additional processing to be done on bean instances before and after their initialization. It is useful for performing custom logic on beans during the initialization process, but it is not necessary for dependency injection to take place.

How exactly does the Spring BeanPostProcessor work?

I am studying for the Spring Core certification an I have some doubts about how Spring handle the beans lifecycle and in particular about the bean post processor.
So I have this schema:
It is pretty clear for me what it means:
The following steps take place in the Load Bean Definitions phase:
The #Configuration classes are processed and/or #Components are
scanned for and/or XML files are parsed.
Bean definitions added to BeanFactory (each indexed under its id)
Special BeanFactoryPostProcessor beans invoked, it can modify the definition of any bean (for example for the property-placeholder values replacements).
Then the following steps take place in the beans creation phase:
Each bean is eagerly instantiated by default (created in right order with its dependencies injected).
After dependency injection each bean goes through a post-processing
phase in which further configuration and initialization may occur.
After post processing the bean is fully initialized and ready for use (tracked by its id until the context is destroyed)
Ok, this is pretty clear for me and I also know that there are two types of bean post processors which are:
Initializers: Initialize the bean if instructed (i.e. #PostConstruct).
and All the rest: that allow for additional configuration and that may run before or after the initialize step
And I post this slide:
So it is very clear for me what does the initializers bean post processors (they are the methods annotated with #PostContruct annotation and that are automatically called immediately after the setter methods (so after the dependency injection), and I know that I can use to perform some initialization batch (as populate a cache as in the previous example).
But what exactly represents the other bean post processor? What do we mean when we say that these steps are performed before or after the initialization phase?
So my beans are instantiated and its dependencies are injected, so then the initialization phase is completed (by the execution of a #PostContruct annotated method). What do we mean by saying that a Bean Post Processor is used before the initialization phase? It means that it happens before the #PostContruct annotated method execution? Does it means that it could happen before the dependency injection (before that the setter methods are called)?
And what exactly do we mean when we say that it is performed after the initialization step. It means that it happens after that the execution of a #PostContruct annotated method, or what?
I can easily figure into my head why I need a #PostContruct annotated method but I can't figure some typical example of the other kind of bean post processor, can you show me some typical example of when are used?
Spring doc explains the BPPs under Customizing beans using BeanPostProcessor. BPP beans are a special kind of beans that get created before any other beans and interact with newly created beans. With this construct, Spring gives you means to hook-up to and customize the lifecycle behavior simply by implementing a BeanPostProcessor yourself.
Having a custom BPP like
public class CustomBeanPostProcessor implements BeanPostProcessor {
public CustomBeanPostProcessor() {
System.out.println("0. Spring calls constructor");
}
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(bean.getClass() + " " + beanName);
return bean;
}
#Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println(bean.getClass() + " " + beanName);
return bean;
}
}
would be called and print out the class and bean name for every created bean.
To undersand how the method fit the bean's lifecycle, and when exactly the method's get called check the docs
postProcessBeforeInitialization(Object bean, String beanName) Apply
this BeanPostProcessor to the given new bean instance before any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method).
postProcessAfterInitialization(Object bean, String beanName) Apply
this BeanPostProcessor to the given new bean instance after any bean
initialization callbacks (like InitializingBean's afterPropertiesSet
or a custom init-method).
The important bit is also that
The bean will already be populated with property values.
For what concerns the relation with the #PostConstruct note that this annotation is a convenient way of declaring a postProcessAfterInitialization method, and Spring becomes aware of it when you either by registerCommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean configuration file. Whether the #PostConstruct method will execute before or after any other postProcessAfterInitialization depends on the order property
You can configure multiple BeanPostProcessor instances, and you can
control the order in which these BeanPostProcessors execute by setting
the order property.
The typical example for a bean post processor is when you want to wrap the original bean in a proxy instance, e.g. when using the #Transactional annotation.
The bean post processor will be handed the original instance of the bean, it may call any methods on the target, but it also gets to return the actual bean instance that should be bound in the application context, which means that it can actually return any object it wants. The typical scenario when this is useful is when the bean post processor wraps the target in a proxy instance. All invocations on the bean bound in application context will pass through the proxy, and the proxy then gets to perform some magic before and/or after invocations on the target bean, e.g. AOP or transaction management.
The difference is BeanPostProcessor will hook into context initialization then call postProcessBeforeInitialization and postProcessAfterInitialization for all defined beans.
But #PostConstruct is just used for the specific class you want to customize bean creation after constructor or set method.

What is the difference between BeanPostProcessor and init/destroy method in Spring?

What is the difference between implementing the BeanPostProcessor interface and either using the init/destroy method attributes in the XML configuration file in Spring or implementing InitializingBean/DisposableBean interface?
This is pretty clearly explained in the Spring documentation about the Container Extension Points.
The BeanPostProcessor interface defines callback methods that you can
implement to provide your own (or override the container's default)
instantiation logic, dependency-resolution logic, and so forth. If you
want to implement some custom logic after the Spring container
finishes instantiating, configuring, and initializing a bean, you can
plug in one or more BeanPostProcessor implementations.
So in essence the method postProcessBeforeInitialization defined in the BeanPostProcessor gets called (as the name indicates) before the initialization of beans and likewise the postProcessAfterInitialization gets called after the initialization of the bean.
The difference to the #PostConstruct, InitializingBean and custom init method is that these are defined on the bean itself. Their ordering can be found in the Combining lifecycle mechanisms section of the spring documentation.
So basically the BeanPostProcessor can be used to do custom instantiation logic for several beans wheras the others are defined on a per bean basis.
Above answers clearly explains some of the very important aspect.
Apart from that it's also important to understand that both beanPostProcessor and init and destroy methods are part of the Spring bean life cycle.
BeanPostProcessor class has two methods.
1) postProcessBeforeInitialization - as name clearly says that it's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.
2) postProcessAfterInitialization - any thing that you want to do after initialization before bean reference is given to application.
Sequence of the questioned methods in life cycle as follows :
1) BeanPostProcessor.postProcessBeforeInitialization()
2) init()
3) BeanPostProcessor.postProcessAfterInitialization()
4) destroy()
You may check this by writing simple example having sysout and check their sequence.
Init and Destroy callback methods are part of Spring bean life cycle phases. The init method is going to be executed after bean instantiation. Similarly, The destroy method is going to be executed before bean finalization.
We can implement this functionality using implementing interfaces InitializingBean and DisposableBean, or using annotations #postconstruct and #predestroy, or declare the <bean> with init-method and destroy-method attributes.
BeanPostProcessor interface is used for extending the functionality of framework if want to do any configuration Pre- and Post- bean initialization done by spring container.
For Example: By default, Spring will not aware of the #PostConstruct and #PreDestroy annotation. To enable it, we have to either register CommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean configuration file. Here CommonAnnotationBeanPostProcessor is predefined BeanPostProcessor implementation for the annotations. Like:
#Required enables RequiredAnnotationBeanPostProcessor processing tool
#Autowired enables AutowiredAnnotationBeanPostProcessor processing tool
And one more main diff is InitializingBean,DisposableBean related afterPropertiesSet() & destory() methods did not accept any paratmeters and return type also void, so we did not implement any custom logic.
But coming to BeanPostProcess methods postProcessBeforeInitialization(Object bean,String beanName) and postProcessAfterInitilization(Object bean,String beanName) are accept those two paramaters and return type also Object so we are able to write initilzation logics as well as any custom login based on the passing bean...
These both callback method feautes are including the bean life cycle and the following are the life cycle as follows
1) BeanPostProcessor.postProcessBeforeInitilazation()
2) #postConstruct or InitializingBean.afterPropertiesSet() or initialization method which is
defining in xml /* here also it's following the same oredr if three ways are availiable **/
3) BeanPostProcessor.postProcessAfterInitialization()
4) #preDestroy or DisposibleBean.destroy() or destroy method which is defining in xml
/* here also it's following the same oredr if three ways are availiable **/
Just a short supplement to all the answers above: If you have any generic logic, common logic that needs to be universally applied to all your Spring beans, such as the injection of a logger to your beans, setting of a properties file, setting default values to fields of your beans through reflection; you could put that logic into ONE single place: the #Overriden callbacks (eg: postProcessBeforeInitialization(Object arg0, String arg1) if you are implementing the BeanPostProcessor interface); instead of duplicating the same logic across all your beans.
a)The postProcessBeforeInitialization() will be called before initialization of the bean.
b)Once the bean gets initialized, the different callbacks methods are called in the following order as per the Spring docs:
Methods annotated with #PostConstruct
afterPropertiesSet() as defined by the InitializingBean callback interface
init method defined through the XML.
The main difference is that the above 3 methods get called after the initialization get completed by the postProcessBeforeInitialization() method.
Once these methods get completed the method postProcessAfterInitialization() will be called and then the destroy methods are called in the same order:
Methods annotated with #PreDestroy
destroy() as defined by the DisposableBean callback interface
destroy() method defined through the XML.

In spring batch framework, what is the difference between 'lazy-init=true' and 'scope=step'?

When I defined a 'MethodInvokingFactory' bean with 'scope=step', I got an error that the type of the bean can't be determined. It worked fine when I replaced 'scope=step' with 'lazy-init=true'. As per my knowledge, both are used for the late binding of the beans, except for that one difference. Are there any other differences between these two ways? Also, is my usage correct?
Please let me know your thoughts about this.
To answer to your question from low-level perspective:
lazy-init="true" means that bean will not be instantiated when the context is created, but will be created when it is referred e.g. by another bean. I think this is clear, also from #AravindA comment.
Scoped bean works in different manner. When context is created this bean is wrapped into additional proxy object (by default created by CGLIB), which is passed to the bean that refers it (this proxy is by default singleton, e.g. shared). So each time the method is invoked on the proxy in runtime Spring intersects the call, requests the factory to return the instance of the bean and invokes the method on that bean. The factory in its turn may lookup for "real" bean instance e.g. in HTTP request ("request" scope) or HTTP session ("session" scope) and/or create new instance if necessary. Late instantiation allows to initialize the scoped bean with "runtime" (scope) values, e.g. values from HTTP request/session which are obviously undefined when context was created. In particular "step"-scoped beans are bound to thread local (remember that steps are run in parallel for partitioning). So, scoped beans are dereferred when you call a method on them. Finally one can easily break this elegant Spring "ideology" by calling any method on scoped bean just after it is set to another bean (e.g. in the setter) :)
One thing to understand about lazy-initialization is that even though a bean
definition may be marked up as being lazy-initialized, if the lazy-initialized
bean is the dependency of a singleton bean that is not lazy-initialized, when the
ApplicationContext is eagerly pre-instantiating the singleton, it will have to
satisfy all of the singletons dependencies, one of which will be the
lazy-initialized bean!
Using a scope of Step is required in order to use late binding since the bean
cannot actually be instantiated until the Step starts, which allows the
attributes to be found. Because it is not part of the Spring container by
default, the scope must be added explicitly, either by using the batch namespace
or by including a bean definition explicitly for the StepScope (but not both):
<bean class="org.springframework.batch.core.scope.StepScope" />
Read here and here for more info
The scope="step" has nothing to do with Lazy initialization . It is use for late binding of parameters inside a "Step" .
the step scope is specifically for latebinding of job/step attributes and not really for late-binding of beans, meaning the spring bean context/factory will enhance stepscoped beans and look for attributes to set, e.g.
value="#{jobParameters[input.file.name]}

Spring destroy-method & half injected objects

In spring I often find myself utilizing the init-method & destroy-method attributes on beans. I'm curious about the contract of these methods. The init-method attribute seems to be called post construction and after all properties have been set. My question is if destroy-method has the same contract. If a setter throws for whatever reason, and the object doesn't have all its properties set, spring won't call the init-method, but I can't find any documentation about spring calling the destroy-method in this situation.
If it does obviously checks for null have to be in place, I'm curious what others do in this situation.
I did a simple test and I found out that in case of a setter throwing an exception both the init and the destroy methods won't be called.
I believe that this is the logical thing to do. A setter shouldn't be allowed to fail - if it does, there is nothing the framework can do to help you. The only reaction to this kind of error is to correct the setter. So I think that your question is irrelevant. Half injected objects shouldn't be allowed.
If you know that a setter could throw an Exception, you should catch it and set a reference to null or do whatever else is appropriate.
The Spring code of interest here is AbstractAutowireCapableBeanFactory.doCreateBean() (I'm looking at the Spring 3 M4 source, but it should be essentially the same for Spring 2.5). The the last thing this method does is register the bean for disposal, and it only does that if the rest of the method (including instantiation and initialization) succeeds. So if any part of the bean initialization fails, the destroy-method callback won't be invoked.

Resources