9.2.3.3. Use a Qualifier to Resolve an Ambiguous Injection

Summary

This task shows an ambiguous injection and removes the ambiguity with a qualifier. Read more about ambiguous injections at Section 9.2.3.1, “About Ambiguous or Unsatisfied Dependencies”.

Example 9.5. Ambiguous injection

You have two implementations of Welcome, one which translates and one which does not. In that situation, the injection below is ambiguous and needs to be specified to use the translating Welcome.
public class Greeter {
  private Welcome welcome;

  @Inject
  void init(Welcome welcome) {
    this.welcome = welcome;
  }
  ...
}

Procedure 9.3. Resolve an Ambiguous Injection with a Qualifier

  1. Create a qualifier annotation called @Translating.

    @Qualifier
    @Retention(RUNTIME)
    @Target({TYPE,METHOD,FIELD,PARAMETERS})
    public @interface Translating{}
    
  2. Annotate your translating Welcome with the @Translating annotation.

    @Translating
    public class TranslatingWelcome extends Welcome {
        @Inject Translator translator;
        public String buildPhrase(String city) {
            return translator.translate("Welcome to " + city + "!");
        }
        ...
    }
    
  3. Request the translating Welcome in your injection.

    You must request a qualified implementation explicitly, similar to the factory method pattern. The ambiguity is resolved at the injection point.
    public class Greeter {
      private Welcome welcome;
      @Inject
      void init(@Translating Welcome welcome) {
        this.welcome = welcome;
      } 
      public void welcomeVisitors() {
        System.out.println(welcome.buildPhrase("San Francisco"));
      }
    }
    
Result

The TranslatingWelcome is used, and there is no ambiguity.