Page 1 of 3 123 LastLast
Results 1 to 10 of 26

Thread: bean reinstanciation upon request

  1. #1
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default bean reinstanciation upon request

    Am I correct to assume that using scope prototype will only create a new instance of the bean when fetching it with getBean()?

    I have a bean that is depended on a bean which is depended on another bean.
    Like this.
    Code:
    <bean id="bean1"...>
      <property name="bean2" ref="bean2"/>
    </bean>
    
    <bean id="bean2"...>
      <property name="bean3" ref="bean3"/>
    </bean>
    
    <bean id="bean3".../>
    bean 3 maintains a list which is different on each datasource I use. I need to have bean2 to update this value(a new instance of bean3) when I switch datasource with AbstractRoutingDataSource.

    I have tried scope="prototype", but it did not work. I assume it is because of what I stated above.

    I have two versions of my application. One with Spring MVC and one withouth(The one with was an experimentation of MVC). The one withouth MVC is getting the Servicebeans with applicationContext.getBean("bean1"). I guess I could try scope="request" in the MVC version of my application, but then the XML editor in eclipse is complaining about "the content of element type bean must match ..." when I add <aop:scoped-proxy/>

  2. #2
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Quote Originally Posted by DJViking View Post
    Am I correct to assume that using scope prototype will only create a new instance of the bean when fetching it with getBean()? ...
    More or less.

    If you have bean1 and bean2 scoped to prototype and bean1 is injected in the bean2 as property, then each time as you fetch bean2 it would refer to the new copy of bean1 (while bean1 was not directly fetched by your code).

    Regards,
    Oleksandr

  3. #3
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default

    Quote Originally Posted by al0 View Post
    More or less.

    If you have bean1 and bean2 scoped to prototype and bean1 is injected in the bean2 as property, then each time as you fetch bean2 it would refer to the new copy of bean1 (while bean1 was not directly fetched by your code).

    Regards,
    Oleksandr
    I have tried having scope protoype on bean1,bean2 and bean3, but still no effect on new instance of bean3 when I getBean("bean1").

    I wonder if I am doing something wrong. I am now using scope="prototype" in bean. Spring version is 2.0.5. I call getBean("bean1") two times and compare them and they are equal! That tells me that prototype scoping does not work.
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext .xml");
    Bean1 b1 = applicationContext.getBean("bean1");
    Bean1 b2 = applicationContext.getBean("bean1");
    System.out.println((b1 == b2)); gives true
    Last edited by DJViking; Jul 25th, 2007 at 07:38 AM.

  4. #4
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Quote Originally Posted by DJViking View Post
    I have tried having scope protoype on bean1,bean2 and bean3, but still no effect on new instance of bean3 when I getBean("bean1").

    Sound weird. I use this quite regularly w/o troubles.

    How you have proved that it was not new instance?
    Have you tried something like this
    Code:
    System.out.println(System.identityHashCode(this);
    in the constructor of bean3

    Code:
    System.out.println(System.identityHashCode(bean3);
    in the setBean3() setter of bean1?

    Regards,
    Oleksandr

  5. #5
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default

    Quote Originally Posted by al0 View Post
    Sound weird. I use this quite regularly w/o troubles.

    How you have proved that it was not new instance?
    Have you tried something like this
    Code:
    System.out.println(System.identityHashCode(this);
    in the constructor of bean3

    Code:
    System.out.println(System.identityHashCode(bean3);
    in the setBean3() setter of bean1?

    Regards,
    Oleksandr
    I don't have access to the code for bean1, bean2 and bean3 as they come from an external API I include in my application. I merly use them in my application when defined in the application context.

    System.identityHashCode gives my two equal values for two getBean with scope="prototype"

  6. #6
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Quote Originally Posted by DJViking View Post
    I don't have access to the code for bean1, bean2 and bean3 as they come from an external API I include in my application. I merly use them in my application when defined in the application context.

    System.identityHashCode gives my two equal values for two getBean with scope="prototype"

    That you have no access to source code of the bean1, bean2, bean3 does nothing, as you always can create a test case that uses your oun beans.

    Concerning your second statement - do I undestand properly that in the
    following code fragment
    Code:
    Object o1= ac.getBean("bean1");
    System.out.println(Ste.identityHashCode(o1);
    Object o2= ac.getBean("bean1");
    System.out.println(Ste.identityHashCode(o2);
    both println() statements produces the same output while bean1 has prototype scope?
    Sorry, but I do not believe it. Can you post your code snippet, output and configuration?

    Regards,
    Oleksandr

  7. #7
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default

    Quote Originally Posted by al0 View Post
    That you have no access to source code of the bean1, bean2, bean3 does nothing, as you always can create a test case that uses your oun beans.

    Concerning your second statement - do I undestand properly that in the
    following code fragment
    Code:
    Object o1= ac.getBean("bean1");
    System.out.println(Ste.identityHashCode(o1);
    Object o2= ac.getBean("bean1");
    System.out.println(Ste.identityHashCode(o2);
    both println() statements produces the same output while bean1 has prototype scope?
    Sorry, but I do not believe it. Can you post your code snippet, output and configuration?

    Regards,
    Oleksandr
    Yes both println() gives the same output
    Last edited by DJViking; Jul 25th, 2007 at 09:19 AM.

  8. #8
    Join Date
    Aug 2006
    Location
    Now Germany, previously Ukraine
    Posts
    1,546

    Default

    Just small but complete test to prove my disbelief

    Main class (A.java)
    Code:
    import org.springframework.beans.*;
    import org.springframework.context.*;
    import org.springframework.context.support.*;
    
    public class A {
        public static void main(String[] args) {
            ApplicationContext ac= new ClassPathXmlApplicationContext("myContext.xml");
            System.out.println("First fetch of B1 ["+ac.getBean("B1")+"]");
            System.out.println("Second fetch of B1 ["+ac.getBean("B1")+"]");
        }
    }
    Class for bean1 (B1.java)
    Code:
    public class B1  {
       Object fBean2;
       public void setBean2(Object bean2) {
          fBean2= bean2;
          System.out.println("Bean2 ["+System.identityHashCode(bean2)+"]");
       }
    }
    Class for bean2 (B2.java)
    Code:
    public class B2  {
       Object fBean3;
       public void setBean3(Object bean3) {
          fBean3= bean3;
          System.out.println("Bean3 ["+System.identityHashCode(bean3)+"]");
       }
    }
    and for bean3 (B3.java)
    Code:
    public class B3  {
    }
    and now context (myContext.xml)
    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.xsd">
    
        <bean id="B1"  class="B1" scope="prototype">
            <property name="bean2" ref="B2"/>
        </bean>
    
        <bean id="B2"  class="B2" scope="prototype">
            <property name="bean3" ref="B3"/>
        </bean>
    
        <bean id="B3"  class="B3" scope="prototype"/>
        
    </beans>
    and, just for completness, log4j.properties
    Code:
    log4j.rootLogger=INFO, console
    
    #Console
    log4j.appender.console=org.apache.log4j.ConsoleAppender
    log4j.appender.console.layout=org.apache.log4j.PatternLayout
    log4j.appender.console.layout.ConversionPattern=%d %p [%c] - <%m>%n
    and now output
    Code:
    2007-07-25 15:25:03,453 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dd5b: display name [org.springframework.context.support.ClassPathXmlApplicationContext@dd5b]; startup date [Wed Jul 25 15:25:03 CEST 2007]; root of context hierarchy>
    2007-07-25 15:25:03,594 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [myContext.xml]>
    2007-07-25 15:25:03,923 INFO [org.springframework.context.support.ClassPathXmlApplicationContext] - <Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@dd5b]: org.springframework.beans.factory.support.DefaultListableBeanFactory@a37368>
    2007-07-25 15:25:03,954 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - <Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@a37368: defining beans [B1,B2,B3]; root of factory hierarchy>
    Bean3 [4116479]
    Bean2 [29987161]
    First fetch of B1 [B1@65a77f]
    Bean3 [30911772]
    Bean2 [10883428]
    Second fetch of B1 [B1@bfc8e0]
    So you see that all bean instances are different. So check your code and configuration once more - somewhere there is error.

    Regards,
    Oleksandr

  9. #9
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default

    My code goes something like this.

    Code:
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    
        SomeService someService = (SomeService) applicationContext.getBean("someService");
        SomeService someService2 = (SomeService) applicationContext.getBean("someService");
        
        System.out.println("Equal?: " + (someService == someService2));
        System.out.println(System.identityHashCode("Bean1 Hash: " + someService));
        System.out.println(System.identityHashCode("Bean2 Hash: " + someService2));
    Code:
          <bean id="someService" class="SomeServiceImpl" scope="prototype">
                <property name="someUtilities" ref="someUtilities" />
          </bean>
    
          <bean id="someUtilities" class="SomeUtilities" scope="prototype">
                <property name="someUtilities" ref="someUtilities" />
          </bean>
    
          <bean id="someTypeUtilities" class="SomeTypeUtilities" scope="prototype">
                <constructor-arg ref="jdbcTemplate" />
          </bean>
    And the output is the same for both instances.
    Last edited by DJViking; Jul 25th, 2007 at 09:23 AM.

  10. #10
    Join Date
    Jun 2007
    Location
    Oslo, Norway
    Posts
    153

    Default

    I can't seem to figure it out. Previous successes was an error. It seems that even though SomeService is defined as prototype it is not getting a new instance with getBean
    Last edited by DJViking; Jul 25th, 2007 at 09:14 AM.

Posting Permissions

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