2 Replies Latest reply on Jul 21, 2011 9:47 PM by roflchap

    Confused about the scope of producer methods

    roflchap

      Hi,


      Per the Weld docs, the default scope for the producer methods is @Dependent. So if I am not wrong, if I had a class like this:


      @Model
      public class MemberRegistration {
      
          @Produces
          @Named
          public Member getNewMember() {
              return new Member();
          }
      
      }



      A new Member would be created for each injection point. Now if we change the scope of getNewMember() to @RequestScoped:


      @Model
      public class MemberRegistration {
      
          @Produces
          @Model
          public Member getNewMember() {
              return new Member();
          }
      
      }



      One Member would be created per each request, no matter how many injection points there are in the app.


      But what about this class:


      @Model
      public class MemberRegistration {
      
          private Member newMember;
      
          @Produces
          @Named
          public Member getNewMember() {
              return newMember;
          }
      
          @PostConstruct
          public void init() {
              newMember = new Member();
          }
      
       
      }



      As far as I can tell, the newMember field is not a CDI bean as it's created using the new operator. But as the scope of getNewMember() is @Default, it's expected to have one new Member per injection point. But the getNewMember() returns the same instance variable every time. This is confusing me.


      Is CDI returning a new instance using reflection/enhancement? If so, why not change it to:


      @Produces
      @Named
      public Member getNewMember() {
          return new Member();
      }
      




      instead? I don't know whether one new instance of Member is created per each injection of getNewMember() or if they all will refer to the same instance?


      Thanks in advance.

        • 1. Re: Confused about the scope of producer methods
          haye



          As far as I can tell, the newMember field is not a CDI bean as it's created using the new operator. But as the scope of getNewMember() is @Default, it's expected to have one new Member per injection point. But the getNewMember() returns the same instance variable every time.

          The scope of getNewMember() determines when the method is called not the lifetime of the returned object (unless it's a dependent bean promoted to some other scope). In your example, you're returning 'newMember' which is a field in a Requestscoped bean. This field and its containing bean will exist for the whole request. So if within one request there are multiple injection points that require an instance of Member, the producer method will be called each time since it's a dependent-scoped producer but the same 'newMember' will be returned. For the next request a new 'newMember' will be returned.



          To return a new, dependent, managed Member instance:




          @Model
          public class MemberRegistration {
          
              @Produces
              @Named
              public Member getNewMember(@New Member newMember) {
                  return newMember;
              }
          
          }





          To return a new, managed Member instance per request (the same instance will be used for all injection points):




          @Model
          public class MemberRegistration {
          
              @Produces
              @Model
              public Member getNewMember(@New Member newMember) {
                  return newMember;
              }
          
          }





          The new Member instance injected into the producer is promoted to request scope.



          Hope that clears things up.





          • 2. Re: Confused about the scope of producer methods
            roflchap

            Thanks for the excellent explanation! :)