Search code examples
javainversion-of-controlcdiweld

Why are Producers not inherited in CDI


Given the following classes

    private static class ProducedInSubClass {
    }

    private static class ProducedInSuperClass {
    }

    public static class SuperClass {    
        @Produces
        public ProducedInSuperClass producedInSuperClass = new ProducedInSuperClass();
    }

    public static class SubClass extends SuperClass {
        @Produces
        ProducedInSubClass producedInSubClass = new ProducedInSubClass();
    }

   public static class BeanWithSubClass {          
        @Inject
        SubClass subClass;
        @Inject
        ProducedInSuperClass producedInSuperClass;
        @Inject
        ProducedInSubClass producedInSubClass;
   }

The injection of ProducedInSuperClass stays unsatisfied. That is consistent with the CDI-Spec Chapter 4.2, I know.

To make this work, I need to extend SubClass by

 @Produces
 ProducedInSuperClass producedInSuperClassInSubClass = producedInSuperClass;

can anybody give an explanation for that? Why are Injects, Annotations Interceptors... inherited but not Producers?


Solution

  • Why are ... inherited but not Producers?

    Excerpt from JavaDoc of @Produces:

    Producer methods and fields are not inherited by bean subclasses.

    If producer methods and fields would be inherited then there would exist multiple beans ... eligible for injection to the injection point which CDI treats as ambiguous dependency.

    On the other hand, CDI supports producer method specialization:

    @Mock
    public class MockShop extends Shop {
    
       @Override @Specializes
       @Produces
       PaymentProcessor getPaymentProcessor() {
          return new MockPaymentProcessor();
       }
    
       @Override @Specializes
       @Produces
       List<Product> getProducts() {
          return PRODUCTS;
       }
    
       ...
    
    }