#PostConstrution called multiple times - spring

I have created a class which implements two interfaces.
I have used a init method with #postconstruction annotation
I am observing that though bean is initialised only during start up, init method is called multiple times.

The #PostConstruct method will be called every time the bean is instantiated. This means either every time you do a "new", or, if you've registered your class with a #Service, #Repository, or any other anotation of sorts that registers the class as a spring bean, the first time you #Autowired it.
Watch out for instantations of the class aside from those if you are using another framework annotations like #ManagedBean in JSF, which could be instantiating your class without you realising it.

Related

Spring's BeanFactory getBean method returns JDK proxy when using #Async (with custom thread executor)

I am new to spring and trying to understand the framework. I have a class (say ClassA) which has execute() method. I am using "prototype" scope (#Scope) for this class.I am using #Async("customThreadPoolTaskExecutor) for this execute() method. I have already defined this customThreadPoolTaskExecutor in another class with #Configuration. Then I have another class (say ClassB) which uses BeanFactory of spring to get an object of ClassA using beanFactory.getBean(ClassA).
I am getting an error on this line inside ClassB
ClassA A = (ClassA) beanFactory.getBean(ClassA);
Error is as below
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'ClassA' is expected to be of type 'ClassA' but was actually of type 'jdk.proxy2.$Proxy103'
Note that above code works fine and returns an object of ClassA if I remove #Async from execute() method of ClassA.
I am looking to understand the root of the problem and clear some of my concepts about spring. What is the relationship between #Async and bean creation using BeanFactory's getBean method. Why does it work without #Async but not with #Async.
Note : The fix/workaround I have so far is to add "ScopedProxyMode" for ClassA as "TARGET_CLASS". After adding this to ClassA's #Scope annotation, things work ok but I am not able to understand the root cause of the issue.

Injecting singleton into prototype in spring

What will be the behavior of class loading of injecting singleton into prototype bean ?
I have tried other way round injecting prototype in singleton and resolving the issue using lookup method.
It depends, if you use a BeanFactory or not. A BeanFactory can load classes lazily.
Without BeanFactory
If from the start until the end of a Spring-Context the concrete Implementation of the Singleton and the Prototype is known, they are load at least if the start-method of the Context is called. The default class-initializations of a Class in java is done by the used ClassLoader.
That means, before the beans are autowirable,
implements-interfaces and extends-classes are iniaitlized.
the static-class-scope is called,
the static fields are initialized and set.
After that, the Context starts using the start-method.
The Default-Constructor of the Singleton is called.
The {} scope is called.
All #Autowired fields are set.
If the Singleton extends the SmartSingletonInitializer, its inherited methods are called.
The #PostConstruct-method is called.
Then if a prototype Bean is required (either by context.getBean or by direct #Autowired, the Prototype's.
The Default-Constructor of the Singleton is called.
The {} scope is called.
All #Autowired fields are set.
If the Prototype extends the SmartSingletonInitializer, its inherited methods are called.
The #PostConstruct-method is called.
The Prototype-Instance is injected.
With BeanFactory
It might behave different because the Prototype bean can return a instance of a Bean that not yet has been load from the corresponding classloader. If so, the prototype bean is load in this order in-time:
implements-interfaces and extends-classes are iniaitlized.
the static-class-scope is called,
the static fields are initialized and set.
The Default-Constructor of the Singleton is called.
The {} scope is called.
All #Autowired fields are set.
If the Prototype extends the SmartSingletonInitializer, its inherited methods are called.
The #PostConstruct-method is called.
The Prototype-Instance is injected.

Qualifier in Spring JavaConfig

I'm trying to write one JavaConfig file, which will contain all dependencies to have the ability to choose injected class.
For example one function of JavaConfig
#Bean
#Qualifier("bigWheel") // Has no impact (I have several types of wheel)
public Car getCar(Wheel wheel){
return new Car(wheel);
}
Also when I mark Car class with #Component I got "No default constructor" exception. What I'm doing wrong?
You have to realize that when Spring is creating your spring context and instantiating the beans it needs default constructors i.e. constructors without any parameters. Quite simply it wouldn't know what Wheel to supply.
I also think you're likely to be unhappy using the pseudo-reserved get/set methods as an object name. Regardless of your Qualifier annotation you are creating an object getCar of class Car.
It kinda looks like you are trying to make getCar a factory method? I'm not going to write a big description in case that's not what you're doing. But if so your pattern needs some work.
EDIT: From your comment below I really don't think you want a bean instantiated at context creation time. It sounds like you just want a regular Spring Aware bean that can use Cars and Wheels. Something like This.
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
class Wheel {
... wheel stuff
}
#Component
#Scope(BeanDefinition.SCOPE_PROTOTYPE)
class Car {
... car stuff
}
#Component
class Dealership extends ApplicationContextAware {
#Autowired
ApplicationContext applicationContext;
... bunch of dealership code
Wheel wheel = (Wheel) applicationContext.getBean("Wheel");
Car car = (Car) applicationContext.getBean("Car");
car.setWheel(wheel);
... profit
It just doesn't sound like you are looking for a global singleton called wheel that is injected into the global singleton car, during context initialization.
That is why I added the SCOPE_PROTOTYPE annotations above. Normally Spring will instantiate an object and keep injeting that object when you call for it. This works well most of the time. But if your object starts storing state or if you're multithreaded of course, that doesn't work.
But Spring can't figure that out. So if you want a unique object instantiated for each getBean call, you have to add the #Scope annotation.
Hope this helps

Inconvenient of #Value Annotation in Spring 3.0

I'm wondering if I add a #Value annotation on a property, the class who contains this property cannot be used by another one with a different value, Example :
MyClassUtil.java had
#Value("${some.value}")
private int _myProperty;
And of course there is one module.properties who contain :
some.value=10
Another class ClassA.java wants to use this class with value 10. Ok, no problem.
But another class ClassB.java wants to use this class but with another value : 20. I cannot do this if I'm not mistaken.
Because before #Value era, I could declare two beans in the moduleContext.xml without any problem.
So, is #Value pushes you to do some strong coupling ?
You are right that the annotation configuration can not be instance specific. It is important to understand the concept of bean definitions in bean factory.
Manual bean definition:
Single <bean> element in your XML config leads to a single bean definition. Multiple <bean> mean multiple definitions (regardless of a bean type).
Single #Bean method within #Configuration class leads to a single bean definition. Multiple #Bean methods mean multiple definitions (regardless of a bean type).
However when using component scan, classes annotated with #Component-like annotations are auto-registered as a single bean definition. There is no way you can register bean multiple times via component scan.
Similarly, annotation configurations (#Value, #Autowired, etc.) are type-wide. Your bean instances are always augmented and processed with the same effect (e.g. injecting the same value). There is no way you can alter annotation processing behaviour from instance to instance.
Is this tight coupling? It is not in its general understanding - bean factory (Spring) is still free to inject whatever it thinks is suitable. However it is more of a service lookup pattern. This simplifies your life when working with domain specific singletons. And most beans in an application context tend to be singletons, many of them domain specific (controllers, services, DAOs). Framework singletons (non-project specific reusable classes) should never use annotation based configuration - in this scope, it is an unwanted tight coupling.
If you need different bean instances, you should not use annotation configuration and define your beans manually.

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.

Resources