Spring lookup-method Example

0

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

Share.

Comments are closed.