0

I am not experienced in EJB and CDI and I am trying currently to apprehend some basic principles of them and how to use it. In particular I want to grasp the purpose and use of Qualifiers and I have read the guide. I cannot understand however completely, how a Qualifier serves as an extention of an interface. Taking as staring point the example in the guide and the statement: "a qualifier is like an extension of the interface. It does not create a direct dependency to any particular implementation. There may be multiple alternative implementations of @Asynchronous PaymentProcessor!", I assume that one can do:

@Asynchronous

public class AsynchronousPaymentProcessor implements PaymentProcessor {

   public void process(Payment payment) { ... }

} 

and

@Asynchronous

public class OtherAsynchronousPaymentProcessor implements PaymentProcessor {

   public void process(Payment payment) { ... }

}

and then they try to inject as:

@Inject @Asynchronous PaymentProcessor asyncPaymentProcessor;

How is it in this case determined, which bean is injected, since both are annotated with the same Qualifier? Or do the multiple implementations of a qualifier concern only Alternatives?

Update-Complete:

I have read the relevant questions as well. What I want is an answer without quite a long description: Since I can inject the type class which implements an interface, what is the benefit of injecting the interface type, other that achieving loose coupling? If I try the above code with 2 @Asynchronous implementations and I receive an Exception, then I infer that it (multiple implementations) is attainable only with alternatives. Am I right?

arjacsoh
  • 8,932
  • 28
  • 106
  • 166
  • Please take a look at this answer, especially the section titled "Are qualifiers needed at all?" http://stackoverflow.com/questions/15231255/understanding-the-necessity-of-type-safety-in-cdi/15313148#15313148 – rdcrng Aug 17 '13 at 11:54
  • Also, your example is not following the guide correctly, in this case you would get an UnambiguousDependecyException. In the guide they have two qualifiers, `@Synchronous` and `@Asynchronous`. – rdcrng Aug 17 '13 at 11:58
  • Or for the example where they use `@Asynchronous` on both implementations, they add additional qualifiers. – rdcrng Aug 17 '13 at 12:05

1 Answers1

0

From the spec, section 5.2:

A bean is assignable to a given injection point if:

  • The bean has a bean type that matches the required type. For this purpose, primitive types are considered to match their corresponding wrapper types in java.lang and array types are considered to match only if their element types are identical. Parameterized and raw types are considered to match if they are identical or if the bean type is assignable to the required type, as defined in Section 5.2.3, “Assignability of raw and parameterized types” or Section 8.3.1, “Assignability of raw and parameterized types for delegate injection points”.

  • The bean has all the required qualifiers. If no required qualifiers were explicitly specified, the container assumes the required qualifier @Default. A bean has a required qualifier if it has a qualifier with (a) the same type and (b) the same annotation member value for each member which is not annotated @javax.enterprise.util.Nonbinding.

In short, the container looks for all the beans that satisfy the type of the injection point, then injects the one bean that whose set of qualifiers matches the set of the qualifiers on the injection point. If no bean matches, you get unsatisfied dependencies, or if more than one bean matches, you get unambiguous dependecies.

Community
  • 1
  • 1
rdcrng
  • 3,415
  • 2
  • 18
  • 36
  • That's pretty close. In CDI (actually JSR 330), the qualifiers and the type of the object combined are the full type of the injection point. Qualifiers add further meta type information to the injection point. – LightGuard Aug 18 '13 at 05:54
  • @LightGuard So, you'd rather have me rephrase that the container simply matches the type of the injection point to the type of a bean given that qualifiers complement that type of both for the purpose of injection, instead of stating that the container first matches the type, then the qualifiers, or is is something else? – rdcrng Aug 18 '13 at 16:08
  • Which way the container does it is more of an implementation detail. If all three implementations are doing it the same way that's simply a coincidence, it isn't mandated by the spec to do it a particular way. Simply adding further clarification. – LightGuard Aug 18 '13 at 19:27
  • @LightGuard You're right. However, I phrased it this way not because of how it is implemented but rather to point out that although any particular bean may implement multiple interfaces just one is enough for a match (which I guess it is obvious why) whereas *all* (the set of all qualifiers) must match exactly. – rdcrng Aug 18 '13 at 19:35