6 Replies Latest reply on Dec 16, 2009 1:49 PM by Adam Warski

    Programmatic injection, interceptors for producers

    Adam Warski Master

      Hello,


      I've got in fact three questions:


      1) Is there a way to programmatically obtain a current bean instance? Something similar to the Component.getInstance method in Seam. I was looking through Weld classes and docs but obviously didn't find anything.


      2) I have a producer method for beans that implement an interface, let's say IMyBean. The method is:


      @Produces public IMyBean getMyBean() { return new MyBeanA(); }



      Is there a way to intercept calls to the methods of the produced instances? Writing:


      @Produces @MyInterceptor public IMyBean getMyBean() { return new MyBeanA(); }



      intercepts the factory method call, not calls to the resulting bean.


      3) Finally, something I also encountered when defining the producer. If I have two implementations if IMyBean, both of them plus the result of the producer method will satisfy the injection point IMyBean. To use only the producer method, I annotated both of the implementation with @Alternative. Is there another (proper) way to tell Weld don't try to use this as bean?


      Adam

        • 1. Re: Programmatic injection, interceptors for producers
          Gavin King Master

          Adam Warski wrote on Dec 14, 2009 22:41:


          Hello,

          I've got in fact three questions:

          1) Is there a way to programmatically obtain a current bean instance? Something similar to the Component.getInstance method in Seam. I was looking through Weld classes and docs but obviously didn't find anything.


          See here.


          2) I have a producer method for beans that implement an interface, let's say IMyBean. The method is:

          @Produces public IMyBean getMyBean() { return new MyBeanA(); }



          Is there a way to intercept calls to the methods of the produced instances? Writing:

          @Produces @MyInterceptor public IMyBean getMyBean() { return new MyBeanA(); }



          intercepts the factory method call, not calls to the resulting bean.



          See here.


          3) Finally, something I also encountered when defining the producer. If I have two implementations if IMyBean, both of them plus the result of the producer method will satisfy the injection point IMyBean. To use only the producer method, I annotated both of the implementation with @Alternative. Is there another (proper) way to tell Weld don't try to use this as bean?


          That is one good way. Another possibility is to annotate the beans @Any. We probably need to add this to the docs, since it is something people will run into very often. Alternatively, it's very easy to write a @NotInjectable portable extension that calls ProcessAnnotatedType.veto().

          • 2. Re: Programmatic injection, interceptors for producers
            Adam Warski Master

            Gavin King wrote on Dec 15, 2009 02:16:



            Adam Warski wrote on Dec 14, 2009 22:41:


            Hello,

            I've got in fact three questions:

            1) Is there a way to programmatically obtain a current bean instance? Something similar to the Component.getInstance method in Seam. I was looking through Weld classes and docs but obviously didn't find anything.


            See here.


            But that's different - I still need to inject the Instance<MyClass> somehow. I'm asking about a situation where I'm in a non-Weld-managed instance, for example when I want to call a service from legacy code.



            2) I have a producer method for beans that implement an interface, let's say IMyBean. The method is:

            @Produces public IMyBean getMyBean() { return new MyBeanA(); }



            Is there a way to intercept calls to the methods of the produced instances? Writing:

            @Produces @MyInterceptor public IMyBean getMyBean() { return new MyBeanA(); }



            intercepts the factory method call, not calls to the resulting bean.


            See here.


            Ok, so it's a no in my case :).


            Thanks,
            Adam

            • 3. Re: Programmatic injection, interceptors for producers
              William Drai Newbie

              You can do a lookup of the BeanManager in JNDI.


              BeanManager manager = (BeanManager)new InitialContext().lookup("java:comp/BeanManager");
              
              Bean<IMyBean> myBean = manager.getBeans(IMyBean.class).iterator().next();
              IMyBean instance = (IMyBean)manager.getReference(myBean, IMyBean.class, manager.createCreationalContext(myBean));
              



              But maybe there is a simpler solution.

              • 4. Re: Programmatic injection, interceptors for producers
                Alexander Bell Newbie

                Be careful with such a solution becaus if you use either Qualifiers or Alternatives you get a collection of Beans in line 2. If you want to take the first bean in the colleciton the solution is ok if you don't want this behaviour it causes in a problem which is very hard to find afterwards.

                • 5. Re: Programmatic injection, interceptors for producers
                  William Drai Newbie

                  It seems to me that getBeans() only returns beans qualified with @Default by default.


                  You can get a collection of beans by querying on @Any with :


                  manager.getBeans(IMyBean.class, new AnnotationLiteral<Any>() {})
                  



                  • 6. Re: Programmatic injection, interceptors for producers
                    Adam Warski Master

                    Ah, so you even can do it in a portable way - nice! :)


                    Although this will work only in EE.


                    Adam