Search code examples
javajakarta-eedependency-injectioncdi

CDI method injection and bean inheritance in Java


What I want to do - I have a child and parent class. Child has SimpleFoo, Parent needs Advaced foo. So,

@Dependent
public class SimpleFoo {
}

@Dependent
public class AdvancedFoo extends SimpleFoo {
}

@Dependent
public class Child {

    private SimpleFoo foo;

    @Inject
    protected void setFoo(SimpleFoo foo) {
        this.foo = foo;
    }
}

@Dependent
public class Parent extends Child {

    @Inject
    @Override
    protected void setFoo(SimpleFoo foo) { //How to inject here AdvancedFoo
        super.setFoo(foo);
    }
}

I know that I can do it via constructor injection but I need method injection. How to do it? Can it be done without using names (like MyBean1) but only using classes (AdvancedFoo)?


Solution

  • Use qualifiers - you now have two beans which both fulfill your requirements on type; you need to limit that and qualifiers are made for such cases.

    Here is how to do it, first the qualifier:

    @Qualifier
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.TYPE, ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD })
    public @interface MyQualifier {
    }
    

    Now, make your AdvancedFoo bean use that qualifier:

    @Dependent
    @MyQualifier
    public class AdvancedFoo extends SimpleFoo {
    ...
    }
    

    And finally, in the init method, inject a bean of type SimpleFoo and with qualifier @MyQualifier:

    @MyQualifier
    public class Parent extends Child {
    
        @Inject
        protected void setFoo(@MyQualifier SimpleFoo foo) {
            this.foo = foo;
        }
    }