Announcement Announcement Module
Collapse
No announcement yet.
Object graph prototype Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Object graph prototype

    Hello,
    simple question:

    Is it possible to have object graph prototype in Spring?
    To be more exact, I need to define in the XML files the folowing graph of objects:

    A references X, B references X, C references X,
    A references B, A references C

    Here, the X is referenced 3 times. What I want to get in one getBean("A") call is a graph of 4 object instances, i.e. only one instance of X referenced by objects A, B and C.

    Obviously, each time I call the getBean("A") I want to get new graph of objects, thus singleton is not a solution here.

    Is it somehow supported? Any solution welcomed?

    Marcel Kruzel
    Trema Czech s.r.o

  • #2
    You can use the singleton attribute on the bean level:

    Code:
    <bean class="Prototype" singleton="false">
    each call context.getBean() will result in a now bean if you set the singleton flag to false.

    I assume this is what you meant?

    regards,
    Alef Arendsen

    Comment


    • #3
      Thanx, but ...
      no, that's not what I meant - prototypes are not sufficient.
      What I want to get after obtaining object A via getBean("A") is:
      A.referenceToX == A.referenceToB.referenceToX

      I want to stress, that I am not interested in just one object,
      all I want is graph of objects created and wired for me!

      If I make all of them prototypes (singleton="false") the formula above
      will not hold since object A and object B will reference different
      object X (two prototypes of X).

      What I want to have are "singletons" per one getBean() method call.

      Hope, I clarified the issue.

      Marcel

      Comment


      • #4
        Object graph

        One solution would be to have a FactoryBean do this for you:


        public class AFactoryBean
        implements FactoryBean,
        InitializingBean {

        private X x;
        private B b;
        private C c;
        private A a;

        public void setX(X x) {
        this.x = x;
        }

        public void setB(B b) {
        this.b = b;
        }

        public void setC(C c) {
        this.c = c;
        }

        public Object getObject()
        throws Exception {
        return a;
        }

        public Class getObjectType() {
        return null;
        }

        public boolean isSingleton() {
        return false;
        }

        public void afterPropertiesSet()
        throws Exception {
        a = new A();
        a.setB(b);
        a.setC(c);
        a.setX(x);
        a.getB().setX(x);
        a.getC().setX(x);
        }
        }


        <bean id="a" class="AFactory">
        <property name="x"><bean class="X" /></property>
        <property name="b"><bean class="B" /></property>
        <property name="c"><bean class="C" /></property>
        </bean>

        This will give you the object graph you want with a new shared X
        instance every time.

        This may force

        Comment


        • #5
          This should work using the correct combination of singleton=false and singleton=true

          Code:
          A = prototype
          B = prototype
          
          X = singleton
          
          with A referencing X and B and B referencing X
          This combination will result in one X bean for the entire context and new A and B beans for every ctx.getBean("A") call and also ctx.getBean("B") will deliver a new B bean.

          If for every call to ctx.getBean("A") you want to have exactly one new X bean created (referenced by both A and B), that's not possible with different combinations of the singleton flag. There are other possibilities, such as a ThreadLocalTargetSource, which creates one new bean for every thread. Of course you can also define the bean twice (maybe using the parent attribute if you need to set many properties).

          Hope this helps a bit?

          regards,
          Alef Arendsen

          Comment


          • #6
            Yes, that's what I meant. The FactoryBean is less than optimal solution
            as the object graph is quite complex.

            I'll look at the ThreadLocalTargetSource, since it seems similar
            to me (I need one per getBean request, not per thread).

            Thanx!

            Marcel

            Comment


            • #7
              Just throwing in another thought here...

              Maybe put the definitions for A,B,C,X in a separate context file, make them all singletone, and instantiate the context everytime you need an "instance of the whole graph"?

              It's probably not elegant either, and there is some performance penalty from reloading the context. On the other hand, you wouldn't have to hardwire the dependencies in a factory bean.

              Comment


              • #8
                Yes, good idea! but

                I need some of the objects in the graph (like C) reference
                some singletons, etc. Thus all I need is only one context.

                It would be nice to be able to define three kinds of objects
                1) prototypes
                2) singletons
                3) graphons :-)

                It might be an interesting enhancement of the Spring in further versions.

                For now, what I did is some extending of Spring classes and with help of ThreadLocal and overriding getBean() method I was able to emulate the desired behavior. Don't know though whether it will work 100%, but as for now it seems OK.


                BR,

                Marcel

                Comment

                Working...
                X