consider a case when a prototype-scoped bean is injected into a singleton scoped bean,
when we try to access prototype-scoped bean using the singleton-scoped bean, we are returned with the same bean every time i.e. the bean injected at the time of singleton initialization.
if we want to get different instances everytime we use a scoped proxy.
I did not get the concept how this scoped proxy works behind the stage and how it magically gives us a new instance even if the bean is present inside a singleton.
From the Spring documentation:
3.4.4.5. Scoped beans as dependencies
Being able to define a bean scoped to a HTTP request or Session (or indeed a custom scope of your own devising) is all very well, but one of the main value-adds of the Spring IoC container is that it manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject a (for example) HTTP request scoped bean into another bean, you will need to inject an AOP proxy in place of the scoped bean. That is, you need to inject a proxy object that exposes the same public interface as the scoped object, but that is smart enough to be able to retrieve the real, target object from the relevant scope (for example a HTTP request) and delegate method calls onto the real object.
…
To create such a proxy, you need only to insert a child element into a scoped bean definition (you may also need the CGLIB library on your classpath so that the container can effect class-based proxying; you will also need to be using Appendix A, XML Schema-based configuration). So, just why do you need this element in the definition of beans scoped at the request, session, globalSession and 'insert your custom scope here' level? The reason is best explained by picking apart the following bean definition (please note that the following 'userPreferences' bean definition as it stands is incomplete):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Related
I have read that whenever we do getBean() in spring, it returns desired object.
So does it mean, if i write call getBean() 1000 times, thousand object will be created ??
If yes, Than how Spring manages these objects ?
if No, Please explain how Spring works with respect to object creation ?
Is there something Object pool kind of concept ?
Please clarify my doubts. I am new to spring and is very confused whether spring framework is created to make our task easy or to make things more complicated.
Spring seems to be a web of XMLs :(
From the Spring Framework documentation on singleton bean factory scope:
The singleton scope
Only one shared instance of a singleton bean is managed, and all
requests for beans with an id or ids matching that bean definition
result in that one specific bean instance being returned by the Spring
container.
To put it another way, when you define a bean definition and it is
scoped as a singleton, the Spring IoC container creates exactly one
instance of the object defined by that bean definition. This single
instance is stored in a cache of such singleton beans, and all
subsequent requests and references for that named bean return the
cached object.
To sum it up, no, Spring will create only a single instance of each bean in a bean factory unless you change the default scope of singleton to some other bean scope.
Other bean scopes include:
Bean scopes
singleton (Default) Scopes a single bean definition to a
single object instance per Spring IoC
container.
prototype Scopes a single bean
definition to any number of object instances.
request Scopes a single bean definition to the
lifecycle of a single HTTP request; that is, each HTTP request has its
own instance of a bean created off the back of a single bean
definition. Only valid in the context of a web-aware Spring
ApplicationContext.
session Scopes a single
bean definition to the lifecycle of an HTTP Session. Only valid in the
context of a web-aware Spring ApplicationContext.
global session Scopes a single bean definition to the
lifecycle of a global HTTP Session. Typically only valid when used in a portlet
context. Only valid in the context of a web-aware Spring
ApplicationContext.
In our project, we use Spring request scoped beans. Now we've a requirement to support async requests and request scoped beans don't work for child threads. I'm aware of RequestContextFilter and it's "support" for async but it appears that RequestContextFilter expects the main thread to wait for the child threads to finish, which isn't the case for us. Our main thread immediately returns after spawning new threads using #Async annotation and DispatcherServlet clears out the RequestContextHolder. Thus when the child threads get to the point where they need a request scoped bean, #Autowired fails.
I'm also aware of SimpleThreadScope but it doesn't clean up thread-local attributes and in a thread-pooling situation, is not only dangerous to use but downright useless.
What I need is a custom scope. So far, I've found 3 useful examples but all of them fall short in that the beans they instantiate as part of the custom scope are plain POJOs without any dependencies. Needless to say that's non-existent in a real life application. Can anyone suggest a way to instantiate custom scoped beans that have #Autowired dependencies on beans from other scopes?
What I found so far:
https://github.com/spring-by-example/spring-by-example/tree/master/modules/sbe-thread-scope/src/main/java/org/springbyexample/bean/scope/thread
https://github.com/billkoch/spring-async-mdc
Spring Bean Custom Scope JMS
Continuing the discussion from the other question's answer here...
See the Spring Documentation about scoped beans as dependencies.
.
I'm referring to the <aop:scoped-proxy/> which is what the link points to. Each time the autowired field is referenced, your custom scope's get() method is called to lookup the instance based on some criteria.
.
I understand I can look up the dependencies (though unsure how, a scope isn't a bean, perhaps I need to pass application context during instantiation?). What I don't understand is how to inject those dependencies into my bean if those're marked #Autowired? Or are you saying the custom scoped bean shouldn't have #Autowired dependencies?
It works automatically; Spring injects a proxy for the bean and the scope.get() is invoked on every method call on that bean, returning the specific instance you want in the context of the current invocation.
Take a look at the AbstractRequestAttributesScope to see how it works (in that case, gets the instance from the HTTP Request and, if it doesn't exist, creates it).
So, your code calls foo() on the proxy; the framework calls the scope to get the desired instance and then calls foo() on that instance.
The exposed methods you wish to call must either be on an interface or not declared final.
Normally it is said that when you create your own scope, and Autowire a scoped object in your class,
It will inject the proxy object, and proxy object will call the method on the target bean.
So this means spring stores a list of object, and based on proxy's call it will give us the desired
object. Am i right? please explain
I don't know where that is said. Spring does not create proxies for scoped beans by default (you have to ask for it, e.g. with ). Once a proxy is created it is no different with a scoped bean than any other - the application context is a map from bean name to bean instance, and some of the beans are proxies.
How does Spring know when to call 'destory' method on a session/request scoped bean (in other words, how does it detect that the concerned bean is going out of scope)?
I read somewhere that it uses request/session listeners to be notified of these events. But these listners need to be defined in web.xml, and there's no mention of defining such listeners in Spring literature. So how does this work?
The org.springframework.web.servlet.DispatcherServlet does it. It uses own code, e.g. the org.springframework.web.context.request.RequestAttributes#registerDestructionCallback callback list functionality to register all these scoped beans.
and there's no mention of defining such listeners in Spring literature
Oh, there is:
To support the scoping of beans at the request, session, and global session levels (web-scoped beans), some minor initial configuration is required before you define your beans.[...]
If you use a Servlet 2.4+ web container, [...] you need to add the following javax.servlet.ServletRequestListener to the declarations in your web applications web.xml file[...]
From: 4.5.4.1 Initial web configuration.
Also note that Spring does not call destroy on prototype-scoped beans.
You can implement the interface DisposableBean and InitializingBean for session scoped bean.
The org.springframework.beans.factory.InitializingBean interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The InitializingBean interface specifies a single method afterPropertiesSet().
Implementing the org.springframework.beans.factory.DisposableBean interface allows a bean to get a callback when the container containing it is destroyed. The DisposableBean interface specifies a single method destroy().
Read more about it here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-nature
I am trying to better understand Spring instantiation of beans. To illustrate my doubts, let's assume we have a Service class being wired in a Controller, here are the questions:
How will Spring manage the lifecycle
of the Controller? Will a new object
be created per request?
Once a Service is instantiaded and
wired to a Controller, will Spring
re-use that object reference to wire
it in to other beans?
Like Servlets, Controllers' lifecycle spans beyond requests. All of controllers in the application are instantiated only once when application is started; afterwards those objects are re-used to service all requests.
As Bozho pointed out, by default all beans are in singleton scope, therefore they will be re-used everywhere, unless specified otherwise.
The default scope is singleton, which means beans will be re-used (i.e. 1) no, a new object will not be created per request, and 2) yes, the object reference will be reused).
This can all be configured. Have a look at http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes.
It all depends on the bean scope. By default all beans are in singleton scope - that is, they are instantiated by the container only once.
If you specify #Scope("request") (or the xml equivalent) then the same service object (singleton) will be injected in all instances of the request-scoped controller. (But you rarely need request-scoped controllers)