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:
spring-core
spring-context
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-method
s. 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. |