The instances passed to my producer does represent effective beans?
#Qualif1
#Prodcues
B qualif1(#Any Instance<B> instances){
return instances.select(B1.class).get(); // Select instance of B1 which extends B
}
I am wondering if instances are already beans or only the selected one will be a bean managed by the container?
Thanks in advance
This does not depend on using instances, but on the scopes of the beans. A call to get works like any other injection point: if you get a prototype bean, a new instance of the bean gets created. If you get an eager singleton - it is already created before you call get.
It seems like your question stems from mixing up beans and instances of beans: the former are definitions (and are all, in a sense "managed" by the container), the latter are instances (which are in the direct sense "managed").
The ladder of abstraction goes like this:
class -> bean -> instance
So the "bean" is neither a class (although in some projects every bean is also a class) nor an instance (although in some projects every bean is also an instance).
Personally, I blame Spring for blurring the boundaries between the three, by encouraging usage of eager singletons for practically everything.
Related
I'm studying spring beans and came across #Lookup, it says:
If we happen to decide to have a prototype Spring bean, then we are
almost immediately faced with the problem of how will our singleton
Spring beans access these prototype Spring beans?
hmm, I don't get it, because when I studied scope=prototype it says:
4.4.2 The prototype scope
The non-singleton, prototype scope of bean deployment results in the creation of a new bean instance every time a
request for that specific bean is made
so it seems i misinterpreted the words:
a request for that specific bean is made
actually programming in spring framework every line of the code is inside of some bean (i.e. #controller, #Service, etc), isn't it?
And almost all of them are singletons, isn't it?
So if I need prototype I just make scope=prototype and almost everytime it's injected to another bean (i.e. #controller, #Service, etc) isn't it?
So please give a real world scenarios, 1) when one should use #Lookup and 2) when it's not needed
Ok for the 1) the scenario:
#Component
#Scope("prototype")
public class SchoolNotification {
// ... prototype-scoped state
}
#Component
public class StudentServices {
// ... member variables, etc.
#Lookup
public SchoolNotification getNotification() {
return null;
}
// ... getters and setters
}
Please, show me scenario for the 2) case, and explain please the difference
Thank u
The implicit Bean scope in Spring is Singleton.
That means for a JVM instance, only a single instance of a Bean exists in memory (theoretically).
When you #Autowire a Prototype-scoped Bean inside a Singleton-scoped Bean, that Prototype one becomes a sort-of-singleton. Just think about it; a Singleton gets created, its injectable fields get Autowired, and that is it, the instance lives forever along with all its fields (keep in mind those Prototype-scoped fields are "pure" instances, they're not proxied).
#Lookup
is a proxy-driven annotation. What that means is Spring will extend your class using JDK proxies or CGLIB proxies, and it will override/implement the #Lookup-annotated method, providing its own version which uses a BeanFactory#getBean each time it is invoked.
The documentation is clear on this point
An annotation that indicates 'lookup' methods, to be overridden by the
container to redirect them back to the BeanFactory for a getBean call.
Thus, that means a fresh Bean instance is returned every time.
Just for your knowledge, another approach for working with Prototype-scoped Beans inside "other"-scoped Beans is using ProxyFactoryBean. The only difference is that the proxy is created at configuration-time, and then made available for direct #Autowireing, thus not requiring the definition of a #Lookup method, which sometimes is not wanted (usually by folks that are obsessed with clean code, like me).
I have the similar problem as described in this thread: http://forum.spring.io/forum/attic/spring-modules/22590-can-t-cache-result-of-inner-method-call
But I don't like to decompose my bean in a chain just for caching. In my case I need to create a chain of three fake beans just for caching!
I understand that the caching proxy just delegates all calls to the original bean, so inner calls cannot be intercepted. I understand this in case of java config -- I've just created my bean with the 'new' keyword. But why I got the same behavior on xml config? I expect that Spring can extend my class with its constructors and create an instance of a new class. So all inner calls will be also go through the caching layer due to polymorphism.
Is there any way to force inheritance but not delegation to the original bean?
Thanks,
Alexey
I've just found the chapter in the reference. It says that "Spring AOP is proxy-based." There is a way to access reference to a real proxy: AopContext.currentProxy()) to call it instead of "this" bean.
I have the following spring configuration.
<bean id="abcService1" class="com.service.ABCServiceImpl" />
<bean id="abcService2" class="com.service.ABCServiceImpl" />
Will spring create 2 instances with different ids for the above configuration?If yes then although both the bean definitions are singleton we still have 2 instances of the same object in the context. Would that mean that its not a singleton any more?
Yes. Two seperate instances will be created. Yes this is not a singleton anymore in a classical meaning (one instance per JVM) - (if ever was), however the created bean (each of them) has a singleton scope (in a Spring meaning). If you really want to assure that an object of a given class will be always a singleton (only one instance per JVM) see Correct way of making a singleton a Spring bean.
But the question is if you really need 'the real singleton'?!
See http://docs.spring.io/spring/docs/3.2.1.RELEASE/spring-framework-reference/html/beans.html#beans-factory-scopes
Yes, the object will no more be Singleton.
By default all Spring injected beans are Singleton, but if you define the same bean twice with two different ids then Spring will create two instances.
I have a class as follows.
public class MyClass {
public void doSomething(){
//B b = //some how get new instance of B each time when doSomething is called
//do it now
}
}
Does spring provides something has something inbuilt like this?
OR i will have to create a factory myself which will create and return B each time get method of factory is called?
This is possible, and documented in the manual:
In most application scenarios, most beans in the container are singletons. When a singleton bean needs to collaborate with another singleton bean, or a non-singleton bean needs to collaborate with another non-singleton bean, you typically handle the dependency by defining one bean as a property of the other. A problem arises when the bean lifecycles are different. Suppose singleton bean A needs to use non-singleton (prototype) bean B, perhaps on each method invocation on A. The container only creates the singleton bean A once, and thus only gets one opportunity to set the properties. The container cannot provide bean A with a new instance of bean B every time one is needed.
A solution is to forego some inversion of control. You can make bean A aware of the container by implementing the ApplicationContextAware interface, and by making a getBean("B") call to the container ask for (a typically new) bean B instance every time bean A needs it.
[...]
Lookup method injection is the ability of the container to override methods on container managed beans, to return the lookup result for another named bean in the container. The lookup typically involves a prototype bean as in the scenario described in the preceding section. The Spring Framework implements this method injection by using bytecode generation from the CGLIB library to generate dynamically a subclass that overrides the method.
I've been playing with Spring and had a quick question...
I have a loop within class A which instantiates new objects of class B. To do this I've used the new operator however I cannot reference any Spring beans injected into instances of class B as I get a null pointer exception. I think I understand that this would be due to spring not managing these instances as beans and therefore not being able to manage the lifecycle however I was just wondering what the best way to go about creating multiple instances would be i.e. should I used appContext.getBean("beanA"); ?
First - are right with your assumptions. Using new means spring doesn't manage the object.
Solutions can be:
appContext.getBean("beanA"), where the bean is of scope "prototype". You obtain the appContext by injecting it, or by implementing ApplicationContextAware
using #Configurable and apsectJ weaving. That way even objects instantiated with new become managed by spring (the weaver plugs into the compiler or the vm)
using a lookup-method - it's the same as the first option (again requires prototype-scoped bean), but you get a method of your class that returns a new instance each time you call it.
Normally, however, you shouldn't need that. In the rare cases you do, I'd recommend the 3rd option.