Search code examples
javacdiweld

Specifying different subclass implementations in CDI


I have two classes, A and B, which need to use a service. There are two services, S1 and S2. S2 extends S1. I wish to inject S1 into class A and S2 into class B. How can I accomplish this in CDI?

public class S1 {}
public class S2 extends S1 {}

public class A {
    @Inject S1 service;  //Ambigious?  Could be S1 or S2?
}

public class B {
    @Inject S2 service;
}

Solution

  • The @Typed annotation enables restricting bean types so that you can write:

    public class S1 {}
    
    @Typed(S2.class)
    public class S2 extends S1 {}
    
    public class A {
        @Inject S1 service;
    }
    
    public class B {
        @Inject S2 service;
    }
    

    In your deployment, beans types of the bean class S2 will be restricted to S2 and Object so that there will only one bean whose bean types contain type S1 and the ambiguous resolution will be resolved.

    Note that the @Typed annotation is available since CDI 1.0.

    You could rely on qualifiers as well though it is preferable to use qualifiers for functional semantic.