Announcement Announcement Module
Collapse
No announcement yet.
How-To wire internal beans of prototype Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How-To wire internal beans of prototype

    A simple question for spring experts or developers

    Is it possible to wire internal beans of a prototype bean using standard spring features, or would it be easy/hard/impossible to add this as feature?

    I'll give you an example of what I'm thinking of. The example doesn't really make sense, because there would be better ways to solve the problem in the example, however I want to keep it as simple as possible. The real case has something to do with wiring EventListeners and UI components in a dialog. Assume I have two simple interfaces (only for clarity) and some classes:

    Code:
    public class Operand {
      public Integer value;
    }
    
    public interface Function() {
      public Integer getResult();
    }
    
    public class Sum implements Function {
      public Operand op1;
      public Operand op2;
      public Integer getResult() {
        return op1.value + op2.value;
      }
    }
    
    public class MyBean {
      public Operand a;
      public Operand b;
      public Function function;
      
      public Integer call() {
        return function.getResult():
      }
    }
    What I want to do, could be expressed as Java Code:

    Code:
    Operand op1 = new Operand();
    Operand op2 = new Operand();
    op1.value = 3;
    op2.value = 5;
    Function func = new Sum();
    func.op1 = op1;
    func.op2 = op2;
    
    MyBean bean = new MyBean();
    bean.a = op1;
    bean.b = op2;
    bean.function = func;
    
    bean.call() ==> result: 8
    And I would like to do this in the Spring applicationContext like this:

    Code:
      
    <bean id="myBean" class="MyBean" singleton="false">
      <property name="a">
        <bean id="operand1" class="Operand">
          <property name="value"><value>3</value></property>
        </bean>
      </property>
      <property name="b">
        <bean id="operand2" class="Operand">
          <property name="value"><value>5</value></property>
        </bean>
      </property>
      <property name="function">
        <bean class="Sum">
          <property name="op1"><ref id="operand1" /></property>
          <property name="op2"><ref id="operand2" /></property>
        </bean>
      </property>
    </bean>
    Note that the interesting part is that "myBean" is actually a prototype that contains two internal beans ("operand1" and "operand2"). However, I want to supply the same instances of "operand1" and "operand2" to "myBean" AND the "function". The "id" attribute (the bean name) of both internal beans should be valid in a scope that is defined by the prototype bean "myBean".

    Is this currently possible?

  • #2
    Since you defined operand1 and operand2 as singleton, won't that happen anyway?

    Comment


    • #3
      No. Since it's an internal bean (inside a property tag), it cannot be referenced with it's Id. Spring will throw an exception in that case.

      Code:
      Can't resolve reference to bean 'operand1' while setting property '.....

      Comment


      • #4
        Your right, I wrote a simple test using your bean definition. Also, tried 'ref local=....'.

        But, in the reference manual it states: "A bean element inside the property element is used to define a bean value inline, instead of referring to a bean defined elsewhere in the BeanFactory. The inline bean definition does not need to have any id defined. "

        Not sure if this can be used to infer that if an id is used, it will become addressable. If not then it could be a bug or a vague situation in the spec.

        J. Betancourt

        Comment


        • #5
          Inner beans are anonymous prototypes

          Inner beans are not registered with the BeanFactory. Instead their BeanDefinition is stored as the value in the outer bean property's PropertyValue instance. During creation of the outer bean the inner bean's BeanDefinition is resolved into an anonymous prototype. This happens in PropertstoreAbstractAutowireCapableBeanFactory.res olveValueIfNecessary().

          The corresponding JavaDoc states:

          * A BeanDefinition, which leads to the creation of a corresponding
          * new bean instance. Singleton flags and names of such "inner beans"
          * are always ignored: Inner beans are anonymous prototypes.

          Cheers,
          Torsten

          Comment


          • #6
            That makes sense. So, why does Spring allow an ID on an inner bean?

            Comment


            • #7
              I think, that there's little Spring can do against this, except ignoring it. However, the more interesting question (for me) is, how can I solve my problem stated above?

              I can imagine a number of situations where it would be nice to be able to reference internal beans.

              @Torsten: I haven't looked at the Spring sources, but guessing from your response, I assume that it would be rather hard to implement such a feature, and that it's not a topic for the Spring team at the moment. Am I right?

              Comment


              • #8
                Originally posted by Prohaska
                @Torsten: I haven't looked at the Spring sources, but guessing from your response, I assume that it would be rather hard to implement such a feature, and that it's not a topic for the Spring team at the moment. Am I right?
                Not sure (my part is the Eclipse support for Spring). You should create a feature request in JIRA for this.

                Cheers,
                Torsten

                Comment

                Working...
                X