Results 1 to 4 of 4

Thread: Lookup Method Injection - Not creating distinct instance.

  1. #1
    Join Date
    Jul 2012
    Posts
    1

    Question Lookup Method Injection - Not creating distinct instance.

    Hi Folks,
    I'm new to spring, and learning it from Apress Prospring3 book.
    I'm trying an example from that book on "Lookup Method Injection" which demonstrates that new instance of bean is created during each call of lookup method.
    But When I tried the example, I don't see new instance is created for each call? Could someone point me what is wrong?

    Here is the code:
    Code:
    <?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-3.1.xsd">
    
    	<bean id="helper" class="com.adi.prospring.ch4.methodInjection.MyHelper" />
    
    	<bean id="abstractJobToDo" class="com.adi.prospring.ch4.methodInjection.AbstractJobToDo">
    		<lookup-method name="getHelper" bean="helper" />
    	</bean>
    	
    	<bean id="standardJobToDo" class="com.adi.prospring.ch4.methodInjection.StandardJobToDo">
    		<property name="helper">
    			<ref local="helper" />
    		</property>
    	</bean>
    
    </beans>
    
    =================================
    package com.adi.prospring.ch4.methodInjection;
    
    public class MyHelper {
    
    	public void doSomeThing() {
    
    	}
    }
    ==================================
    package com.adi.prospring.ch4.methodInjection;
    
    public interface JobToDo {
    
    	public MyHelper getHelper();
    
    	public void doIt();
    }
    ===================================
    package com.adi.prospring.ch4.methodInjection;
    
    public abstract class AbstractJobToDo implements JobToDo {
    
    	@Override
    	public abstract MyHelper getHelper();
    
    	@Override
    	public void doIt() {
    		getHelper().doSomeThing();
    	}
    
    }
    =====================================
    package com.adi.prospring.ch4.methodInjection;
    
    public class StandardJobToDo implements JobToDo {
    
    	private MyHelper helper;
    
    	@Override
    	public MyHelper getHelper() {
    		return this.helper;
    	}
    
    	@Override
    	public void doIt() {
    		getHelper().doSomeThing();
    
    	}
    
    	public void setHelper(MyHelper helper) {
    		this.helper = helper;
    	}
    
    }
    =========================
    Main class:
    package com.adi.prospring.ch4.methodInjection;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.util.StopWatch;
    
    public class ExecuteJobs {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext(
    				"com/adi/prospring/ch4/methodInjection/xmlBeanFactory.xml");
    
    		JobToDo standardJobToDo = ctx.getBean("standardJobToDo", JobToDo.class);
    		JobToDo abstractJobToDo = ctx.getBean("abstractJobToDo", JobToDo.class);
    
    		displayInfo(standardJobToDo);
    		displayInfo(abstractJobToDo);
    	}
    
    	private static void displayInfo(JobToDo jobToDo) {
    		StopWatch stopwatch = new StopWatch();
    		stopwatch.start("methodInjectionDemo");
    
    		MyHelper helper1 = jobToDo.getHelper();
    		MyHelper helper2 = jobToDo.getHelper();
    
    		System.out.println(jobToDo.getClass().getName()
    				+ " : is helper1==helper2? :" + (helper1 == helper2));
    		System.out.println("helper1=" + helper1);
    		System.out.println("helper2=" + helper2);
    		for (int x = 0; x < 100000; x++) {
    			MyHelper helper = jobToDo.getHelper();
    			helper.doSomeThing();
    		}
    		jobToDo.doIt();
    		stopwatch.stop();
    		System.out.println("Time elapsed=" + stopwatch.getTotalTimeMillis()
    				+ "ms");
    
    	}
    
    }
    ==============================
    Here is code output, which shows new instance is not created for each of getHelper() on abstractJobToDo instance.
    Code:
    com.adi.prospring.ch4.methodInjection.StandardJobToDo : is helper1==helper2? :true
    helper1=com.adi.prospring.ch4.methodInjection.MyHelper@558352d8
    helper2=com.adi.prospring.ch4.methodInjection.MyHelper@558352d8
    Time elapsed=5ms
    com.adi.prospring.ch4.methodInjection.AbstractJobToDo$$EnhancerByCGLIB$$7f0cfb5f : is helper1==helper2? :true
    helper1=com.adi.prospring.ch4.methodInjection.MyHelper@558352d8
    helper2=com.adi.prospring.ch4.methodInjection.MyHelper@558352d8
    Time elapsed=149ms

  2. #2

    Default

    What scope is assigned to the helper bean? Shouldn't it be prototype?

    <bean id="helper" class="com.adi.prospring.ch4.methodInjection.MyHel per" scope="?"/>

    Just a thought...

    Jeff
    Last edited by visualjeff; Jul 24th, 2012 at 02:06 PM.

  3. #3
    Join Date
    Jul 2010
    Location
    Venice, Italy
    Posts
    709

    Default

    As Jeff pointed out, Spring beans are singletons by default, so what is displayed is normal behaviour. If you want a different instance every time you call getBean(), you need to specify prototype scope.

    However, in your case, that evidently wouldn't change much: this is because MyHelper is a field of the StandardJobToDo class, and you only getBean() for that class once. Thus, even with prototype scope on MyHelper, you would get the same instance of MyHelper which is the one saved inside the only StandardJobToDo instance which is instantiated.
    Your code shows poor understanding of dependency injection, scopes, and the mechanics of the Spring framework; I suggest a more torough study of the theory before going 'hands-on'.

  4. #4

    Default

    However, in your case, that evidently wouldn't change much: this is because MyHelper is a field of the StandardJobToDo class, and you only getBean() for that class once. Thus, even with prototype scope on MyHelper, you would get the same instance of MyHelper which is the one saved inside the only StandardJobToDo instance which is instantiated.
    That's true but the original post did *not* expect to see different instance in the StandardJobToDo case. Instead the original post expected the abstractJobToDo case to show different instances, which is correct. Here it is:

    Here is code output, which shows new instance is not created for each of getHelper() on abstractJobToDo instance.
    So with changing the scope of the 'helper' bean to 'prototype' in original posted code, you should see the different instances being returned in the abstractJobToDo case. That is Spring's Method Lookup Injection in action. Helpful this clarifies up some misunderstanding.
    Last edited by tannoy; Jul 31st, 2012 at 01:44 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •