In
my previous post, I explained singleton and prototype bean scopes. In a typical
application, one bean is dependent of more than one bean. If one singleton bean
uses another singleton bean (or) one non-singleton bean uses another
non-singletong bean is absolutly fine. But the problem arises, when the bean
scopes are different.
For example,
If
singleton bean 'A' uses the non-singleton bean 'B'. Whenever the application
request for the instance of 'A', then Spring IOC returns the same instance, since
'A' is of scope singleton. The container cannot provide bean A with a new
instance of bean B every time one is needed.
Lookup method
injection
Lookup
method injection is a technique provided by the Spring IOC container to
override methods on container managed beans, to return the lookup result for
another named bean in the container.
Let’s
see an example without method injection first.
A.java
package com.sample.pojo; public class A { public A() { System.out.println("Constructor A is created"); } private B dependency; public B getDependency() { return dependency; } public void setDependency(B dependency) { this.dependency = dependency; } }
B.java
package com.sample.pojo; public class B { public B(){ System.out.println("Constructor B is created"); } }
myConfiguration.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="a" name="a" class="com.sample.pojo.A"> <property name="dependency" ref="b" /> </bean> <bean id="b" name="b" class="com.sample.pojo.B" scope="prototype" /> </beans>
HelloWorld.java
package com.sample.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.sample.pojo.A; public class HelloWorld { public static void main(String args[]) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "myConfiguration.xml" }); A obj1 = context.getBean("a", A.class); A obj2 = context.getBean("a", A.class); ((ClassPathXmlApplicationContext) context).close(); } }
Output
Constructor A is created Constructor B is created
Notify
the output, the constructors are called once. Since my bean ‘b’ is defined with
prototype scope, I am expecting it to be return new instance on every bean
request of type b.
Now
let’s see how to solve this problem using method injection.
Update
class A like below.
A.java
package com.sample.pojo; public abstract class A { public A() { System.out.println("Constructor A is created"); } public abstract B getDependency(); }
Spring
Framework generate a dynamic subclass of ‘A’ that will override the getDependency
method to provide a new instance of ‘B’ every time it is requested for.
You
can now define the name of lookup-method name in the Myclass bean definition as
this:
myConfiguration.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="a" name="a" class="com.sample.pojo.A"> <lookup-method name="getDependency" bean="b" /> </bean> <bean id="b" name="b" class="com.sample.pojo.B" scope="prototype" /> </beans>
HelloWorld.java
package com.sample.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.sample.pojo.A; public class HelloWorld { public static void main(String args[]) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "myConfiguration.xml" }); A obj1 = context.getBean("a", A.class); A obj2 = context.getBean("a", A.class); obj1.getDependency(); obj2.getDependency(); ((ClassPathXmlApplicationContext) context).close(); } }
Output
Constructor A is created Constructor B is created Constructor B is created
No comments:
Post a Comment