Enterprise Java

Spring lookup-method Example

When a bean has dependency on another bean, we inject the bean using the setter property or through the constructor.

The getter method will return us the reference that is been set but suppose you want a new instance of the dependent bean each time you invoke the getter method, then you will probably have to follow a different approach.

In this article, we will see an example of method injection using lookup-method attribute.

Dependencies

Add the following dependencies:

  1. spring-core
  2. spring-context
  3. spring-beans

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javarticles.spring</groupId>
	<artifactId>springLookupMethodExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>3.2.3.RELEASE</spring.version>
	</properties>

</project>

Method Injection Approaches

How do we get a new instance each time we invoke the getter method? One approach would be to define the dependent bean as prototype and then implement the getter method to return us a new instance calling applicationContext.getBean(beanId).
Issue with this approach is that now your dependent on the applicationContext.

Second approach is let container manage the method injection. The getter method can be abstract, let spring dynamically sub-class the class containing the getter method and implement it to return the configured bean. This way, we can use the same base class and deploy it in different ways to returns us different beans without the need of changing the code.

Method injection using lookup-method

The method in question doesn’t need to be a getter method but it should be a method that returns something. In our example, PizzaShop is an abstract class and has two method makePizza and makeVeggiesPizza() which returns us the veggie Pizza.

PizzaShop:

package com.javarticles.spring;

public abstract class PizzaShop {
   public abstract Pizza makePizza();
   public abstract Pizza makeVeggiePizza();
}

As you can see our example is very simple. Pizza has a static count variable which gets incremented as we create a new instance. It has a boolean member isVeg which will be true if the pizza is vegetarian.

Pizza:

package com.javarticles.spring;

import java.util.concurrent.atomic.AtomicLong;

public class Pizza {
    private static AtomicLong count = new AtomicLong(0); 
    private boolean isVeg;
    
    public Pizza() {
        count.incrementAndGet();
    }
    public String toString() {
        return "A new " + (isVeg ? "veggie" : "") + "Pizza, count(" + count.get() + ")";
    }
    public void setIsVeg(boolean veg) {
        isVeg = veg;
    }
}

We will configure makePizza and makeVeggiePizza as lookup-methods. We have configures a normal pizza and a veggie pizza beans. Each abstract method will have one <lookup-method element. The name attribute will be the method name and the bean will point to the bean configured. Here we have configured both pizza and veggiePizza as prototype beans.

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="pizzaShop" class="com.javarticles.spring.PizzaShop">
		<lookup-method name="makePizza" bean="pizza"/>
		<lookup-method name="makeVeggiePizza" bean="veggiePizza"/>
	</bean>
	
	<bean id="pizza" class="com.javarticles.spring.Pizza" scope="prototype"/>
	
	<bean id="veggiePizza" class="com.javarticles.spring.Pizza" scope="prototype">
		<property name="isVeg" value="true"/>
	</bean>

</beans>

Let’ snow test it. We will first load the context and get the PizzaShop bean. Next, we will make calls pizzaShop.makePizza() and pizzaShop.makeVeggiePizza().

SpringLookupMethodExample:

package com.javarticles.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringLookupMethodExample {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        try {
            PizzaShop pizzaShop = (PizzaShop) context.getBean("pizzaShop");
            Pizza firstPizza = pizzaShop.makePizza();
            System.out.println("First Pizza: " + firstPizza);

            Pizza secondPizza = pizzaShop.makePizza();
            System.out.println("Second Pizza: " + secondPizza);
            
            Pizza veggiePizza = pizzaShop.makeVeggiePizza();
            System.out.println("Veggie Pizza: " + veggiePizza);
        } finally {
            context.close();
        }
    }
}

Each time we invoke the method, it create a new Pizza bean, we can see the count getting incremented.

Output:

First Pizza: A new Pizza, count(1)
Second Pizza: A new Pizza, count(2)
Veggie Pizza: A new veggiePizza, count(3)

Download the source code

This was an example about spring method injection using lookup-method attribute. You can download the source code here: springLookupMethodExample.zip

Reference: Spring lookup-method Example from our JCG partner Ram Mokkapaty at the Java Articles blog.

Ram Mokkapaty

Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button