7 Replies Latest reply on Jun 10, 2010 12:16 AM by Liu Kai

    Seam2.x's @Unwrap in CDI

    s ls Newbie

      In Weld,there is no context variable. How to get @Unwrap's behaviour?


      @Unwrap
      public  Manager getManager(){
         ...
         return manager;
      }





      Thanks.

        • 1. Re: Seam2.x's @Unwrap in CDI
          Stuart Douglas Master

          The easiest way to achieve this would be by registering a stateless normal scope.


          This means that if you had something like:


          @Produces
          @StatelessScoped
          public  Manager getManager(){
             ...
             return manager;
          }
          
          



          you will get a similar effect to @Unwrap (however the producer will be called with every invocation on the injected proxy, so it is slightly different).

          • 2. Re: Seam2.x's @Unwrap in CDI
            s ls Newbie

            Douglas,thanks for your reply.


            There is something that I do not understand.


            1.Why should registe a stateless normal scope ?


            2.Is there apporach to implement Seam2.x's XML configuration,like:




            public class ManagerProxy{
            ...
            @Unwrap
            public  Manager getManager(){
               ...
               return manager;
            }
            ...
            }
            
            public class MyFilter{
            Manager manager;
            ...
            }



            Components.xml



            <test:managerProxy name="manager_proxy" .../>
             <test:myFilter name="my_filter" manager="#{manager_proxy}" .../>



            So,variable manager is dynamically set to Manager's instance.

            • 3. Re: Seam2.x's @Unwrap in CDI
              Liu Kai Newbie

              how about it if using Portable Extension? concretely:


              First: create an annotation just as Seam2's @Unwrap. Then add this @Unwrap to somewhat SomeClass.someMethod. Such as



              public class SomeClass {
                  @Unwrap
                  public OtherClass someMethod {
                      return new OtherClass();
                  }
              }




              Second: create an extension using ProcessAnnotatedType event. Something like:




              public class MyExtension implements Extension {
                   
                     // iterate every bean to find out which bean contains an @Unwrap annotation by using reflection
                  <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> pat) {
                       
                      Class<?> clazz = pat.getAnnotatedType().getJavaClass();
                      
                      for (Method m : clazz.getMethods()) {
                          if (m.isAnnotationPresent(Unwrap.class)) {
                                 // get the actually returned class type
                              Class<?> unwrapclazz = m.getReturnType();
                              pat.setAnnotatedType(unwrapclazz); // ??how to build an AnnotatedType, giving had known unwrapclazz??
                          }
                      }
                  }    
              }



              • 4. Re: Seam2.x's @Unwrap in CDI
                Stuart Douglas Master

                I have just added this into weld-extensions, it is called @ManagedProducer.


                The bean actually injects a dependant scoped proxy, and every time you call a method on the proxy the proxy calls the @ManagedProducer method, and then invokes the method on the returned object:


                @ManagedProduer
                @SomeQualifier
                @Named("manager")
                public  Manager getManager(){
                   ...
                   return manager;
                }
                



                @Inject
                @SomeQualifier
                Manager manager; 
                



                The other part of the @Unwrap, where the owner component was replaced by the result of the method call is no longer relevant in CDI, you can simply put the @Named annotation on the @ManagedProducer method and give the result any name you like.


                • 5. Re: Seam2.x's @Unwrap in CDI
                  s ls Newbie

                  What's the difference between



                  @ManagedProduer
                  @SomeQualifier
                  @Named("manager")
                  public  Manager getManager(){
                     ...
                     return manager;
                  }
                  


                  and



                  @Produces
                  @SomeQualifier
                  @Named("manager")
                  public  Manager getManager(){
                     ...
                     return manager;
                  }



                  • 6. Re: Seam2.x's @Unwrap in CDI
                    Stuart Douglas Master

                    @Produces injects manager once when the bean is created.


                    @ManagedProducer injects a proxy once when the bean is created, and every time a method is invoked on the proxy it calls getManager() again to get the current manager.


                    • 7. Re: Seam2.x's @Unwrap in CDI
                      Liu Kai Newbie

                      Stuart Douglas wrote on Jun 09, 2010 22:59:


                      @Produces injects manager once when the bean is created.

                      @ManagedProducer injects a proxy once when the bean is created, and every time a method is invoked on the proxy it calls getManager() again to get the current manager.




                      but how about it if that's a dependent object, or some other stuffs which cannot be proxied?