Is dependency injected if scope is prototype in Spring if we don't use getBean method - spring

I wanted to know if we only do ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); in our main method and don't do Coach coach1=context.getBean("myCoach5",Coach.class); where suppose "Coach" is my class and "myCoach5" is id of bean having prototype scope defined in applicationContext.xml. Then in case of prototype-scope will constructor led dependency be injected? Will its constructor's content run?
I observe it does not work in prototype scope but works in case of singleton scope with everything else remaining the same.

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.

Spring lookup-method and scoped proxy usage

I'm a bit confused about using method injection (lookup-method) and aop scoped-proxy (Since both used for different scoped beans injection) so
1) When to use method injection and when to use aop-scoped proxy ?
2) What is the reason why a aop-scoped proxy will not be used for a prototype bean ?
Both lookup method injection and scoped proxy are means to inject shorter lived beans into longer lived beans. However, they serve different use cases.
Method injection is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean.
A proxy gets injected in place of the desired bean and provides that bean depending on the context. For example, if a singleton bean (such as a Spring MVC controller) auto-wires a session scoped bean, then the proxy delivers that bean belonging to the current HTTP session.
Such a proxy doesn't apply well to a situation where a prototype bean shall be obtained at runtime. Lookup method injection is one way to obtain prototype instances at runtime.
However, method injection has limitations because it builds upon abstract methods. Hence, certain things like writing unit tests are more cumbersome, as you need to provide a stub implementation of the abstract method. Component scanning doesn't work with abstract classes either.
One alternative to method injection is Spring's ObjectFactory, or its JSR equivalent Provider.
Another, straightforward way of creating prototype bean instances at runtime (which even makes it possible to provide constructor arguments) is to implement a bean factory like the following:
#Configuration
public class MyProvider {
#Bean
#Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyThing create(String name) {
return new MyThing(name);
}
}
Usage:
#Component
public class MySingleton {
#Autowired
private MyProvider myProvider;
public void doStuffThatNeedsAPrototypeBeanInstance() {
MyThing thing = myProvider.create("some name");
...
}
}
For the question 1. When to use method injection and when to use aop-scoped proxy?
Let's say you have a singleton bean A has dependency on the prototype bean B. A has a method m which has B involved.
You got the object a of A and execute the method m several times. Every time m executing, a new object b of B needs to inject to a. That's the time you use the method injection.
Besides, if you have a singleton bean A has dependency on the session bean B. A has a method m which has B involved.
You got the object a of A and execute the method m several times. As long as the execution time is in a same session, a has the same object b of B. That's the time you use proxy.

Spring how to enforce use of bean factory, for prototype beans with runtime arguments

In my spring-boot application i have "normal" singleton beans that "autowire" the stuff they need via a private constructor. So it is not possible to call "new" anywhere in the code.
But i also have "prototype" beans that need runtime arguments to be created. To create such beans i could use this approach (lazy instantiated protype beans): Spring bean with runtime constructor arguments
The problem is that the constructor is used and hence must be "visible". Is there any way in Spring to create such prototype beans with a private constructor? I want to enforce the usage of BeanFactory to create them.
You can try to build your prototype beans with an implementation of
factoryBean,public interface FactoryBean<T> {
T getObject() throws Exception;
Class<T> getObjectType();
boolean isSingleton();
}
So you can encapsulate more complexe logic inside,
A full exemple here

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.

Resources