Spring - Injecting a Prototype Bean into a Singleton Bean Problem

[Updated: Feb 8, 2017, Created: Jan 2, 2016]

If same scoped beans are wired together there's no problem. For example a singleton bean A injected into another singleton bean B. But if the bean A has the narrower scope say prototype scope then there's a problem.

To understand the problem let's see an example. We are going to have two beans MyPrototypeBean, scoped as prototype and MySingletonBean, scoped as singleton. 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.

Example Project

Dependencies and Technologies Used :

  • Spring Context 4.2.3.RELEASE: Spring Context.
  • JDK 1.8
  • Maven 3.0.4

Narrower Scope Bean Injection Example Select All Download
  • narrower-scoped-bean-injection
    • src
      • main
        • java
          • com
            • logicbig
              • example

On running AppConfig main method, we are expecting MySingletonBean to print two different time, with approximately one sec difference. But here's a actual output:

    Hi, the time is 2016-01-02T16:01:55.477
    Hi, the time is 2016-01-02T16:01:55.477

That means there's only one instance of the prototype bean within the singleton bean. Well, a prototype bean should not behave that way. There should be a new instance every time.

The problem is: spring container only creates the singleton bean MySingletonBean once, and thus only gets one opportunity to inject the dependencies into it. The container cannot provide MySingletonBean with a new instance of MyPrototypeBean every time one is needed.

There are three solutions to that problem

  1. Inject ApplicationContext bean into MySingletonBean to get instance of MyPrototypeBean, whenever we need it. Example here.
  2. Lookup method injection. This approach involves in dynamic bytecode generation. Example here.
  3. Using Scoped Proxy.
  4. Using JSR 330 Provider<T> injection by Spring. Example here.
In the next tutorials, we will see example of each solution.

See Also