Spring @Lookup Method Injection

In Spring, the lookup method injection is the ability of the container to override methods on container-managed beans and return a container-managed bean as the lookup result specified as the method return type.

In Spring, the Lookup Method Injection is intended for use when we want to work with two beans of different lifecycle scopes (singleton, prototype etc.). Do not use this when beans are in the same lifecycle scopes.

1. Inspiration for @Lookup Method Injection

The @Lookup Method Injection feature allows a Spring bean to obtain a new instance of a dependency every time a specific method is called. It’s a way to achieve prototype-like behavior for dependencies in a singleton-scoped bean.

The primary inspiration for this design was the classical scoped bean injection problem. In this problem, we want to inject a prototype-scoped bean dependency into a singleton-scoped bean.

Note that SingletonBean and PrototypeBean, both are container-managed beans.

@Component
public class SingletonBean { 
    
    @Autowired
    private PrototypeBean prototypeBean; 
}

A typical solution to the above problem is using the ApplicationContext to get a new instance of PrototypeBean inside a getter method in class SingletonBean.

@Component
public class SingletonBean implements ApplicationContextAware {
    
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

  public PrototypeBean getPrototypeBean() {
      return applicationContext.getBean(PrototypeBean.class);
  }
}

2. Method Injection via @Lookup

In the above solution using the ApplicationContext, we can see the following:

  • It will be almost the same code to solve this problem every time.
  • The ApplicationContext and PrototypeBean, are both managed by the Spring container.

So it makes complete sense to abstract the logic at the framework layer and provides a generic shortcut to apply the solution quickly. The @Lookup annotation serves exactly this purpose. The @Lookup annotation indicates ‘lookup’ methods to be overridden by the container to redirect them back to the BeanFactory for a getBean call.

We can rewrite the previous solution using @Lookup as follows. Both solutions do the exact same thing. They return a new instance of PrototypeBean when the getter method is invoked. The container uses reflection (using CGLIB) to invoke the getter method and override its definition.

@Component
public class SingletonBean {

  @Lookup("prototypeBean")
  public PrototypeBean getPrototypeBean() {
    // This method will be overridden by Spring and return a new instance of PrototypeBean
    return null;
  }

  public void performAction() {
    PrototypeBean prototypeBean = getPrototypeBean();
    // Use the obtained prototype bean
  }
}

Please note that @Lookup is the Java equivalent of the XML element ‘lookup-method’.

<bean id="prototypeBean" class="com.app.PrototypeBean" />

<bean id="singletonBean" class="com.app.SingletonBean">
    <lookup-method name="getPrototypeBean" bean="prototypeBean"/>
</bean>

It is worth mentioning that the body of the lookup method does not matter because it is never executed. If the method is abstract, the dynamically generated subclass implements the method, else subclass overrides the concrete method defined in the original class.

3. When does @Lookup not Work?

As the @Lookup method-based method injection requires the beans to be container-managed, the container should be able to subclass the beans. For this reason, the annotated method must not be private, final or static so the method can be overridden in the subclass.

Also, note that lookup methods would not work on beans returned from @Bean methods in configuration classes. In such a case, consider bean injection using @Inject Provider<PrototypeBean>.

4. Conclusion

In this Spring tutorial, we learned what is method injection, how it is implemented in a Spring container, and how it solved the scoped bean injection problem. We also learned about the @Lookup annotation with examples, and when it will not work in the application code.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.