Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Prototype scoped bean in a singleton

Tags:

java

spring

I am trying to inject a prototype bean in a singleton bean such that every new call to a singleton bean method has a new instance of the prototype bean.

Consider a singleton bean as below:

    @Component     public class SingletonBean {        @Autowired         private PrototypeBean prototypeBean;         public void doSomething() {          prototypeBean.setX(1);          prototypeBean.display();        }     } 

I expect that every time the doSomething() method is called, a new PrototypeBean instance is utilized.

Below is the prototype bean:

     @Component       @Scope(value="prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)      public class PrototypeBean {         Integer x;          void setX(Integer x) {          this.x = x;         }          void display() {           System.out.println(x);         }     } 

What seems to be happening is that spring is being overeager in handing over a new instance of PrototypeBean in the doSomething() method. That is, the 2 lines of code in the doSomething() method are creating a new instance of prototypeBean in each line.

And so in the 2nd line - prototypeBean.display() prints NULL.

What is missing in configuration for this injection?

like image 240
Angad Avatar asked Aug 06 '14 16:08

Angad


People also ask

Can singleton class have prototype scope in Spring?

You cannot dependency-inject a prototype-scoped bean into your singleton bean, because that injection occurs only once, when the Spring container is instantiating the singleton bean and resolving and injecting its dependencies.

What happens when you inject bean with prototype scope in a singleton scope bean?

Let us look at a simple example when a prototype bean injected inside a singleton bean. Individually when a prototype bean used, every time a new instance is expected and for singleton the same instance. Singleton Bean always returns the same bean instance no matter where ever it is being referred.

How do you inject request scoped bean in singleton bean?

As singleton beans are injected only once per their lifetime you need to provide scoped beans as proxies which takes care of that. @RequestScope is a meta-annotation on @Scope that 1) sets the scope to "request" and 2) sets the proxyMode to ScopedProxyMode.


1 Answers

From Spring documentation:

You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes. If you try to create a scoped proxy for a singleton bean, the BeanCreationException is raised.

It seems the documentation has changed a bit for version 3.2 documentation where you can find this sentence:

You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes.

It seems that its not expected you use a proxied prototype bean, as each time it is requested to the BeanFactory it will create a new instance of it.


In order to have a kind of factory for your prototype bean you could use an ObjectFactory as follows:

@Component public class SingletonBean {      @Autowired     private ObjectFactory<PrototypeBean> prototypeFactory;      public void doSomething() {         PrototypeBean prototypeBean = prototypeFactory.getObject();         prototypeBean.setX(1);         prototypeBean.display();     } } 

and your prototype bean would be declared as follows:

@Component  @Scope(value="prototype") public class PrototypeBean {     // ... } 
like image 162
Francisco Spaeth Avatar answered Sep 18 '22 22:09

Francisco Spaeth