6 Replies Latest reply on Oct 24, 2011 7:55 AM by tschleuss

    Component.getInstance() vs. injection

    asookazian

      So we know that all injected properties of a component are dynamically injected prior to business method execution.  This means every time a business method is invoked whether or not those properties need to be re-freshed all of the properties marked @In are re-fresh/re-injected.  So let's take a hypothetical case.  Say we have 20 Seam components that need to be injected into component Foo.


      @Name("foo")
      public class Foo {
          
         @In
         private C1 c1;
      
         
         @In
         private C2 c2;
      
         ...
      
         
         @In
         private C20 c20;
      
         @Begin(join=true)
         public void begin(){
         ...
         }
      
         @End
         public void end(){
         ...
         }
      
         @Destroy
         public void destroy(){...}
      }



      Would it not be more efficient to use Component.getInstance(C1.class) instead of the unnecessarily repetitive and time-consuming swarm of dynamic injections?  For a particular business method, you get the component you need at that exact time.  Instead of getting all 20 of them when you may only need one of them for that particular business method.


      It's kind of like you're a rich person with 20 chauffeurs and every time you step out of your house all 20 of your cars are on and running but you only drive away at that time with one of them.  So why turn on all 20 cars every time you step out of your house?  That's overkill.


      Just wondering if anybody has noticed this and it not actually using @In except when absolutely necessary like injecting SMPC and Log instance via @Logger.


      Out of curiosity, I tried this:


      public void foo(){
           ManagedPersistenceContext smpc = (ManagedPersistenceContext)Component.getInstance(ManagedPersistenceContext.class);
                try {
                     entityManager = smpc.getEntityManager();
                }
                catch (SystemException e){
                     //no op
                }
      }



      and I got:



      java.lang.IllegalArgumentException: No @Name annotation for class: org.jboss.seam.persistence.ManagedPersistenceContext
        • 1. Re: Component.getInstance() vs. injection
          joblini

          Hi Arbi,


          Yes, cost of interceptors (@In) is a known issue, this is discussed by Dan Allen in his excellent article Speed up your Data-Driven JSF/Seam Application by Two Orders of Magnitude


          For the problem you mention with SMPC, I usually just obtain the Entity manager directly, something like


          Component.getInstance(EntityManager.class, true)
          



          In addition, many of the Seam components have static instance() methods, which do the Component.getInstance() call for you, something like


          Logger.instance()
          





          • 2. Re: Component.getInstance() vs. injection
            asookazian

            with


            Component.getInstance(EntityManager.class, true)



            how would you know if the EntityManager instance manages a PC (@PersistenceContext) or SMPC (@In)?

            • 3. Re: Component.getInstance() vs. injection
              israel.bgf

              Maybe i'm VERY wrong, but the @In/getInstance always will get the SMPC.

              • 4. Re: Component.getInstance() vs. injection
                asookazian

                @In always injects SMPC (there's an @Unwrap getEntityManager() in ManagedPersistenceContext class).


                Not sure about getInstance()...


                I just tried this:


                EntityManager entityManager = (EntityManager)Component.getInstance(EntityManager.class, true);



                and got this:


                Caused by: java.lang.IllegalArgumentException: No @Name annotation for class: javax.persistence.EntityManager
                     at org.jboss.seam.Component.getComponentName(Component.java:1801)



                plus for this:


                <persistence:managed-persistence-context name="entityManager"
                                                     auto-create="true"
                                      persistence-unit-jndi-name="java:/boBETSEntityManagerFactory"/>    



                I do not see setAutoCreate() or setName() methods in ManagedPersistenceContext class.


                But I do see a clearDirty() method in ManagedPersistenceContext class but it seems that belongs in the EntityManager interface (but there's a clear() method in that API, not clearDirty()).

                • 5. Re: Component.getInstance() vs. injection
                  swd847

                  You have to do getInstance(entityManager). getInstance(Class) relies on an @Name annotation on the target class to determine the component name. Component.getInstance and injection will always return the same thing (a SMPC).


                  name and autoCreate are availible on all seam components.

                  • 6. Re: Component.getInstance() vs. injection
                    tschleuss

                    How can i inject e component on seam 3,
                    like Component.getInstance on seam 2 ?


                    I'm confuse, i don't know how get component
                    and how i define a componente without a components.xml


                    Thnaks!