inject beans into an abstract class with spring and java ee 5 - spring

I am injecting a spring-managed bean into an abstract class and it seems that it doesn't work. Here is an explanation of what I do, if it is not enough, I can edit the post and add some code:
implement the java code - 1 abstract class, 2 classes that inherit from it and the bean to be injected and used in the abstract class and thus by the subclasses.
define the bean in the spring config.
define the abstract class and 2 subclasses in the spring config.
define the first bean as a property of the abstract class bean.
result - it's not working.
Then I tried to move the injected bean from the abstract class into the two subclasses. Now it works.
So, did I do something wrong, or is it theoretically impossible to inject a bean into an abstract class with spring 3 and Java EE 5?

Is it theoretically impossible to inject a bean into an abstract class with spring 3 and Java EE 5?
Dependency Injection happens on an Object not its Class. Spring injects dependencies into managed beans which are Objects already instantiated by Spring. Since, an Abstract Class cannot be instantiated it would be conceptually wrong to think about DI here.
On a somewhat related note, you can also define a non-abstract Class as an abstract Spring bean by adding the attribute abstract=true to the <bean> tag. This indicates that the bean would not be instantiated and would serve as a mere template of properties that other beans can use through bean inheritance (which isn't related to Java inheritance at all).
In this context as well, (if you've configured it) the Dependency Injection would only happen for the child beans and not their parent bean since it has been defined as abstract. (Note: It's not mandatory for the parent bean to be abstract but it makes sense to do so when all it does is to act as a set of common bean properties.)

Related

Difference between beanFactoryPostProcessor and postProcessBeforeInitialization [duplicate]

I was trying to understand the difference between BeanFactoryPostProcessor and BeanPostProcessor.
I understood that BeanFactoryPostProcessor operates on bean definition i.e. before the bean instance is getting created it gets executed and BeanPostProcessor gets executed after bean is instantiated and lifecycle events are called.
Does this mean BeanFactoryPostProcessor is not a part of spring lifecycle events as it's called before instantiation while BeanPostProcessor is the part of Spring lifecycle events? Kindly verify if my understanding is right.
BeanFactoryPostProcessor is an interface and beans that implement it are actually beans that undergo the Spring lifecycle (Example below) but these beans don't take part of the other declared beans' lifecycle.
public class CustomBeanFactory implements BeanFactoryPostProcessor {
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// Manipulate the beanDefiniton or whatever you need to do
}
}
}
The differences about BeanFactoryPostProcessor and BeanPostProcessor:
A bean implementing BeanFactoryPostProcessor is called when all bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans. This will let you have access to all the beans that you have defined in XML or that are annotated (scanned via component-scan).
A bean implementing BeanPostProcessor operate on bean (or object) instances which means that when the Spring IoC container instantiates a bean instance then BeanPostProcessor interfaces do their work.
BeanFactoryPostProcessor implementations are "called" during startup of the Spring context after all bean definitions will have been loaded while BeanPostProcessor are "called" when the Spring IoC container instantiates a bean (i.e. during the startup for all the singleton and on demand for the proptotypes one)
Here is a flow diagram that might help to understand the spring bean initialisation life cycle.
As we can see, the implementation of theBeanFactoryPostProcessor is executed before any spring bean instantiation, contrary to the BeanPostprocessor, where the implemented method will be executed only when the bean is instantiated.
The source image is from the Spring 5 Design Patterns Book.
I pick the explanation from the book:
After loading the bean definitions from all styles of configurations,
BeanFactoryPostProcessor comes into the picture to modify the
definition of some beans, and then the container instantiates the
beans. Finally, BeanPostProcessor works on the beans, and it can
modify and change the bean object. This is the initialization phase.
Bean Factory Post Procesor (BFPP):
Used when we want to override XML / annotations, because Spring reads XML / annotations to create the beans. If you want to provide a different configuration to Spring during creation (at run time), then you need to use BFPP. Creating the internal dependency graph is a one time process.
Bean Post Processor (BPP):
The above step happened only once. It's like creating the "menu" of beans. After creating the bean, if you want to change the bean properties, you can't make any changes to the XML / annotations. Instead, you can use the BPP for bean configuration change after creation. The BPP has 2 execution areas, one before #postconstruct and one after #postconstruct.
Real Time Example:
You want to place an online food order from Zomato. While ordering online, you give a list of food (XML/annotations) to the restaurant. But, just before the restaurant starts making the food, you call them and ask them to change the dish (BFPP). Now the food is ready to be delivered and you've received it (Bean is created). But you want to make some modifications (like salt or chilly powder), and you can do this before tasting the food (because you know restaurants never put enough salt), or even after tasting the food (this is before and after #postconstruct). Once the taste is good, then the food is ready (the bean is ready to use).
The BeanFactoryPostProcessor executes before bean Object instantiation (ie at the time Applicationcontext container is initialized)
BeanPostprocessor is executed after the bean object is created, as it can be executed before init() and after init().

Spring Beans Configurations

if we have
1- a case scenario where we have class A configured as singleton and a child class B as a member within Class A configured as prototype.
2- Another case scenario, which is the opposite to the first one, where we have Class A defined as prototype and Class B defined as singleton.
How Spring container is gonna initialize and deal with these two situations when request is made to these classes A and B?
Please take a look at this answer - Spring session-scoped beans as dependencies in prototype beans?
You can always inject a bean of wider scope (e.g. a singleton) into a
bean of narrower scope (e.g. a session-scoped bean), but to it the
other way around, you need a scoped-proxy.
This applies to your questions.
You are injecting narrower scope bean in wider scoped bean. (Prototype is narrower than singleton). It should work for you.
You are trying to inject wider scope bean into narrower scoped bean. You need to use a scoped-proxy.

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.

Spring configurable bean injection

Is there any way to inject bean dependencies make configurable except from factory pattern?
I have 3 class implement same interface and have 3 bean definition. I want to change that beans using in other class? For excample is it possile to read bean name form conf file and use it as varible?
Yes, you can go with #Qualifier annotation. As you have 3 classes which implement same interface, name those classes with different names and use #Qualifier annotation.
Spring documentation says : autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring's #Qualifier annotation.

Spring No unique bean of type

i have a little trouble in Spring with two component of a service.
I have this component:
#Component
public class SmartCardWrapper
and this one:
#Component
public class DummySmartCardWrapper extends SmartCardWrapper
The service autowire both but spring fails due this expection:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.cinebot.smartcard.SmartCardWrapper] is defined: expected single matching bean but found 2: [dummySmartCardWrapper, smartCardWrapper]
Why it doesn't use class names?
That's one of the most basic concepts of Spring - Inversion of Control.
You don't need to declare your dependencies using their implementation types (to avoid coupling with implementation). You can declare them using interfaces or superclasses instead, and make Spring find the proper implementation class in the context.
In other words, bean are not distinguished by their implementation classes, because you may want to change implementation class of a bean without changing the beans that depend on it. If you want to distinguish between different beans of the same type, use logical bean names instead:
#Autowired #Qualifier("smartCardWrapper")
private SmartCardWrapper smardCardWrapper;
#Autowired #Qualifier("dummySmartCardWrapper")
private SmartCardWrapper dummySmardCardWrapper;

Resources