Announcement Announcement Module
Collapse
No announcement yet.
Singleton referencing Prototype Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Singleton referencing Prototype

    Hi all,

    I believe this is a simple question but I have not been able to find an answer via the forum, Google, and digging around the documentation. Basically, I have two beans, one is a singleton and the other one is a prototype (non-singleton). The singleton (let's call it A) references the prototype (let's call it b) via method injection. However, each time I get bean A (via the BeanFactory or ApplicationContext), I want B referenced in A to be a new instance. This does not seem to be the behavior in Spring (which is probably correct).

    <bean id="a" class="ClassA">
    <property name="b"><ref bean="b"/></property>
    </bean>

    <bean id="b" class="ClassB" singleton="false">
    </bean>

    Is it possible to get the behavior I described above?

    Thanks,
    Ben

  • #2
    I'm quite interested to know what would happen if you made the prototype bean a scoped proxy (<aop:scoped-proxy/>). The reference manual says you don't have to do it, it doesn't say you can't though.

    Code:
    <bean id="a" class="ClassA">
        <property name="b"><ref bean="b"/></property>
    </bean> 
    
    <bean id="b" class="ClassB" scope="prototype">
        <aop:scoped-proxy/>
    </bean>
    You do not need to use the <aop:scoped-proxy/> in conjunction with beans that are scoped as singletons or prototypes. It is an error to try to create a scoped proxy for a singleton bean (and the resulting BeanCreationException will certainly set you straight in this regard).
    http://www.springframework.org/docs/...ther-injection

    Comment


    • #3
      By the way, I am using Spring 1.2.

      Comment


      • #4
        Originally posted by benw View Post
        However, each time I get bean A (via the BeanFactory or ApplicationContext), I want B referenced in A to be a new instance. This does not seem to be the behavior in Spring (which is probably correct).
        This does not happen for sure in Spring. You only get a new instance of B on each lookup of B. But those lookups only happen when creating the beans where B is a depency. So once A is set up it has its B instance forever. Anything else would not be thread-safe as you could lookup A in one thread while it is in use by another thread.

        Originally posted by benw View Post
        Is it possible to get the behavior I described above?
        Only with Spring 2 and scoped proxy I guess. In 1.2 you have to look up B yourself and do thread-safe injection and access to A - or simply declare A as prototype as well.

        Jörg

        Comment


        • #5
          I guess I didn't dig hard enough at the documentation. In Spring 1.2, there is a specific way to solve this problem using Method Injection (see section 3.3.4). Although it is not the most elegant solution, it works for me. The only caveat is that I need to do:

          getB() in my method when I want to get an instance of B. Otherwise, I get a NullPointerException.

          Ben

          Comment


          • #6
            Method injection (specifically 3.3.4.1. Lookup method Injection) is a safe bet. When you say you have to call getB(), thats the whole point. You get the instance from calling the method. If you still have a field called b, you should remove that. All methods that want access to B should call getB(), therefore scoping the bean at the method rather than class level.

            Current reference docs have a better example of this.
            Code:
            package fiona.apple;
            
            public abstract class CommandManager {
            
               public Object process(Object commandState) {
                  // grab a new instance of the appropriate Command interface
                  Command command = createCommand();
                  // set the state on the (hopefully brand new) Command instance
                  command.setState(commandState);
                  return command.execute();
               }
            
                // okay... but where is the implementation of this method?
               protected abstract Command createCommand();
            }
            http://www.springframework.org/docs/...thod-injection

            Comment

            Working...
            X