Injecting a prototype bean into a singleton bean

spring prototype bean example
lookup spring
autowire prototype bean
inject request scoped bean into singleton
when to use singleton and prototype scope in spring
spring objectfactory
injecting one bean into another
scoped beans as dependencies

I am new to Spring and trying to understand the concept "Injecting a prototype bean into a singleton bean". As per my understanding In singleton, only a single instance per Spring IoC container, no matter how many time you retrieve it. validator.validate(requestId);, because still private RequestValidator validator not instantiated. I developed below example where in a singleton bean I give a reference of prototype bean like below:

<bean id="requestProcessor" class="com.injection.testing.RequestProcessor">
        <property name="validator" ref="validator" />
</bean>

<bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />

RequestProcessor.java

public class RequestProcessor {
    private RequestValidator validator;

    public RequestProcessor(){
        System.out.println("Constructor:: RequestProcessor instance created!");
    }

    public void handleRequest(String requestId){
        System.out.println("Request ID : "+ requestId);
        validator.validate(requestId);
    }

    public RequestValidator getValidator() {
        return validator;
    }

    public void setValidator(RequestValidator validator) {
        this.validator= validator;
    }
}

RequestValidator.java

public class RequestValidator {
    private List<String> errorMessages = new ArrayList<String>();

    public RequestValidator() {
        System.out.println("Constructor:: RequestValidator instance created!");
    }

    // Validates the request and populates error messages
    public void validate(String requestId){
        System.out.println("RequestValidator :"+requestId);
    }

    public List<String> getErrorMessages() {
        return errorMessages;
    }
}

Now when I called the main method I see the following output: MainDemo.java

public class MainDemo {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        RequestProcessor processor = (RequestProcessor) context.getBean("requestProcessor");
        processor.handleRequest("1212");
        System.out.println("------------------------");
        processor.handleRequest("1213");
    }
}

the output is:

Constructor:: RequestProcessor instance created!
Constructor:: RequestValidator instance created!
Request ID : 1212
RequestValidator :1212
------------------------
Request ID : 1213
RequestValidator :1213

Now looking at the output, it looks like for the 2nd call processor.handleRequest("1213"); bean is not instantiated, instead already instantiated bean gets used thats why constructor wont get called again. So Prototype bean validator acting as a singleton bean only.

To me : it is expected that when ever I fetch requestProcessor from application context, it will be wired with a new validator as we declared the validator bean is of prototype scope. But this does not happen.

How to solve it ? Is my understanding correct ?

Another way:

<!-- Lookup way  -->
    <bean id="requestProcessor" class="com.injection.testing.RequestProcessor" >
        <lookup-method name="getValidator" bean="validator" />
    </bean>

    <bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />

If I call my main method I see below output + error: Here code validator.validate(requestId); executes, private RequestValidator validator; is not instatiated and whats why null pointer exception coming.

I've shown in the below code:

public class MainDemo {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        RequestValidator requestValidator = (RequestValidator) context.getBean("validator");

        RequestProcessor processor = (RequestProcessor) context.getBean("requestProcessor");
        processor.handleRequest("1212");
        System.out.println("------------------------");
        processor.handleRequest("1213");
    }
}

Now I see the below error:

Constructor:: RequestProcessor instance created!
Constructor:: RequestValidator instance created!
Request ID : 1212
Exception in thread "main" java.lang.NullPointerException
    at com.injection.testing.RequestProcessor.handleRequest(RequestProcessor.java:12)
    at com.injection.testing.MainDemo.main(MainDemo.java:14)

Injection happens only once, when the Spring context is started. If bean has prototype scope, Spring will create new prototype bean for every injection. But prototype bean will not be created every time you call its methods. Lets consider next example:

<bean id="firstRequestProcessor" class="com.injection.testing.RequestProcessor">
        <property name="validator" ref="validator" />
</bean>

<bean id="secondRequestProcessor" class="com.injection.testing.RequestProcessor">
        <property name="validator" ref="validator" />
</bean>


<bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />

In this case both of RequestProcessor beans will have its own instance of RequestValidator bean.


Lookup method is the method, you should call every time when you need new instance of prototype bean. It's better to make this method abstract, because anyway Spring will override this method automatically. For example:

public class abstract RequestProcessor {

    public void handleRequest(String requestId){
        System.out.println("Request ID : "+ requestId);
        RequestValidator validator = createValidator(); //here Spring will create new instance of prototype bean
        validator.validate(requestId);
    }

    protected abstract RequestValidator createValidator();
}

Note, that createValidator returns instance of RequestValidator and has not any parameters. Also you don't need private class variable validator. In this case bean's configuration will looks like:

<bean id="requestProcessor" class="com.injection.testing.RequestProcessor" >
    <lookup-method name="createValidator" bean="validator" />
</bean>

<bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />

Now every time you call createValidator method, Spring will create new instance of validator bean.

You can find more details in documentation.

Injecting Prototype Beans into a Singleton Instance in Spring , Now, let's inject the prototype-scoped bean into the singleton – and then expose if via the getPrototypeBean() method: ? 1. 2. 3. 4. 5. 6. You cannot dependency-inject a prototype-scoped bean (new instance of bean every time) into your singleton bean, because that dependency injection occurs only once, when the Spring container is instantiating the singleton bean and resolving and injecting its dependencies.


When spring creates the context, it will instantiate an instance of the RequestProcessor. During the instantiation of that instance, an instance of the RequestValidator is created and injected in the RequestProcessor.

Because any subsequent reference to the RequestProcessor Bean will access the same instance of the RequestProcessor in the context - and it is already fully constructed - there will never be a call to create a new instance of a RequestValidator. Although your Validator is scoped to be a prototype - in the example above - you only ever ask for a single copy - when you create the RequestProcessor singleton.

For the second part of your question - you misunderstand the use of the lookup-method. Spring allows you to override the method on your RequestProcessor - so when you call requestProcessor.getValidator() - spring will return a new instance of that RequestValidator. However - during the construction of your requestProcessor instance - you never initialized the validator field. Nor did spring inject a validator during instantiation. Hence the NullPointerException.

Spring, Injecting Spring Prototype bean into Singleton bean. Have you ever wonder why singleton is the default scope for Spring beans? Why isn't it  When you inject prototype bean to singleton bean, prototype bean still behave like a singleton bean. Let’s understand this with the help of example. 1. Create a simple java maven project. 2. Maven dependency. put spring and cglib maven dependency in pom.xml.


Lookup method injection

As noted earlier, lookup method injection is an advanced feature that you should use rarely. It is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this type of configuration provides a natural means for implementing this pattern.

public abstract class CommandManager {
    public Object process(Object commandState) {
        // grab a new instance of the appropriate Command interface
        Command command = createCommand();

        // set the state on the (hopefully brand new) Command instance
        command.setState(commandState);
    return command.execute();
    }

    // okay... but where is the implementation of this method?
    protected abstract Command createCommand();
}

Using Java-configuration support , you can create a subclass of CommandManager where the abstract createCommand() method is overridden in such a way that it looks up a new (prototype) command object:

@Bean
@Scope("prototype")
public AsyncCommand asyncCommand() {
    AsyncCommand command = new AsyncCommand();
    // inject dependencies here as required
    return command;
}

@Bean
public CommandManager commandManager() {
    // return new anonymous implementation of CommandManager with command() overridden
    // to return a new prototype Command object
    return new CommandManager() {
        protected Command createCommand() {
            return asyncCommand();
        }
    }
}

Injecting Spring Prototype bean into Singleton bean, Injection happens only once, when the Spring context is started. If bean has prototype scope, Spring will create new prototype bean for every injection. When you work with a prototype bean in a singleton, you have three options to get a new instance of the prototype: Spring can autowire a single prototype instance when it creates the singleton. It’s the default framework behavior. Spring can create a new prototype instance on every call to any method of this prototype.


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 creates the singleton bean A only 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.

With this approach , our business logic is get coupled with Spring conatiner (Application Context) which does not looks to be a good Solution. An alternate of this is Lookup Method Injection.

Injecting Prototype bean into a Singleton bean in Spring, by Prasanth Gullapalli In Spring, most of the beans we work with are Singletons. If a singleton bean is wired with yet another singleton bean,  When the singleton is created, a new instance of the prototype bean is created and injected in the singleton bean. This causes a problem when someone requests for the prototype bean through the singleton. It can return the only instance of the prototype bean it knows. It won’t ever inject a new prototype bean into it and return it,


Injecting a prototype bean into a singleton bean, You cannot dependency-inject a prototype-scoped bean (new instance of bean every time) into your singleton bean, because that dependency injection occurs  We will inject the prototype bean into the singleton bean. We will also access MySingletonBean via method call context#getBean(MySingletonBean.class) multiple times. We are expecting (per prototype specifications) that a new prototype bean will be created and be injected into MySingletonBean every time.


Injecting a prototype bean into a singleton bean, This means that if you dependency inject a prototype-scoped bean into a singleton-scoped bean, a brand new prototype bean will be instantiated and then​  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 creates the singleton bean A only once, and thus only gets one opportunity to set the properties.


How to Inject Prototype Scoped Bean into a Singleton Bean in Spring, Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then  Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated and then dependency-injected into the singleton bean. The prototype instance is the sole instance that is ever supplied to the singleton-scoped bean.