When do I need to use custom qualifiers?
Custom CDI qualifiers should only be used when: (a) your (non-annotative) code intentionally introduced ambiguity in the type used; (b) you want to enter a more specific type of object than indicated in the code; (c) you want a more flexible type selection and configuration than that provided by the predefined classifier @Named.
Qualifiers eliminate the ambiguity of the type that should be created / entered in the CDI.
(a) and (b) arise when you use high-level types in your code to provide a powerful general algorithm that can be reused and flexibly tuned. For example. it is often possible and it is recommended that you encode the entire algorithm against an interface rather than a specific class — for example, algorithms against a list, map, or queue. But often, these algorithms only work well if we capture specific implementations of the interface, such as SortedList, TreeMap, or PriorityQueue. If the CDI is to act as a factory object, performing the lifecycle management of the object, initializing the correct objects to control injections and dependencies, then he should know the full details.
Custom qualifiers are intelligent and customizable in how they disambiguate the type that CDI creates / introduces. @Named is a much lighter tool. For (c), when I mention "type selection", I mean that a developer can combine several qualifiers together to "logically select" the most suitable type without naming the exact class. @Named effectively requires an exact class nomination - multiple qualifiers will let CDI work for you. Configurability refers to the ability to change the behavior of CDI during deployment by modifying beans.xml (no need to change code / annotations). that is, it can logically configure what CDI does, and it can do this until deployment time - without touching the code or annotations.
When do I need to declare custom qualifiers?
Custom CDI qualifiers do not need to be created for each individual type that can be entered. This is the most important.
Several qualifiers can be used for both injection points and type declarations. CDI matches bean type plus SET OF qualifiers when determining input type. To reduce the number of qualifiers for an ad, it is recommended that you include types in the number of attributes / problems that describe them. Then instead of one qualifier for each type there can be one qualifier for each type attribute - even if such an attribute is multi-valued, for example, Hash / Tree / Enum (see the next paragraph).
Secondly, qualifiers should use the parameters wisely to further reduce the number of declarations required. Instead of creating 10 qualifiers, you can have one qualifier that has a parameter that is a string or, preferably, an enumeration that can take 10 values.
The combination of these two ideas (qualifiers = type attribute PLUS uses qualifier parameters) in the example for the collection library: can types be described using repespenting Sorted / Non-Sorted attributes? Hash / Tree / Array? Linked / Unlinked? If I specify a variable
@Inject @Sorted @Organisation("hash") @Navigation("linked") Map myMap;
then I have a strong choice of type, because each of these aspects is guaranteed to be satisfied, I have a sorted linked hash map, not knowing that this requires a special class in a particular package.
Points have not yet been addressed:
If I use some annotation with the parameterized name bean, how is it really safe?
Strong typing is guaranteed because there must be a complete match with:
- bean type
- set of qualifiers
- set of parameter values
No injectable type can violate any of these things. Instead of thinking about matching types for a single string (package_name.class), consider it to match multiple strings / values that are completely controlled by the developer, these same strings / values are used for both declaration and injection, providing a safe match. Also, instead of thinking that you should correspond to a specific lower-level class, remember that you can correspond to higher-level classes in the inheritance hierarchy and the intelligent use of @Default qualifiers for your types (remember Java EE 6 "smart default settings ")?) will take you to your preferred specific types.
If I use a special classifier for type safety for a service or a Tao (for each interface), then for a large application, such as 1000 or more classes of service or a Tao with several implementations, this will be messy. Then for large applications, is it possible to use a safe type injection?
1000 or more classes of service or tao? Indeed??! This would often mean a big design problem right away. If this is not a single application of super-mega-dimensionality-record-attempt for a complex business such as the tax department or NASA. Even then, it would be normal to break Java EE / SOA into smaller modules with much fewer classes. If this is what you have, you can take a look at simplifying your design - you can have much bigger problems than defining scroll determinants and the past ...
Qualifiers are needed only where type ambiguity exists - that is, many classes of ancestors / descendants in the hierarchy of the same type. It often happens that a relatively small number of service classes or DAOs are ambiguous.
As described above, do not use the one-qualifier-per-implementation-class template: instead, refactoring uses the qualifier-per-type attribute, and use the imprint parameters templates for each classifier
You can use safe type injection with large applications.
If the answer to the above question is “No,” then what's the point of using type safety?
- The answer is yes.
- the proposed scenario (1000+ services / DAO classes) is very rare.
Even if it's possible to write annotations for type safety in large applications, is it really worth the effort to just avoid the detailed xml configuration?
The goal of CDI is not only to “avoid a detailed xml configuration”, CDI has the following objectives:
- Support for areas (including the new web chat area) with object lifecycle management
- Type dependency injection mechanism, including the ability to select dependencies at the development or deployment stage without detailed configuration
- Support for Java EE modularity and Java EE component architecture - The modular structure of a Java EE application is considered when resolving dependencies between Java EE components
- Integration with the Unified Expression Language (EL), allowing you to use any context object directly on the JSF or JSP page
- Ability to decorate injectable objects
- Ability to associate interceptors with objects through interceptor type bindings
- Event Notification Model
- Web chat context in addition to the three standard web contexts defined by the Java Servlets specification.
- SPI allowing portable extensions to integrate with the container
This WAY is different and more useful than the basic XML configuration file turned into annotations - even earlier basic annotations for embedding Java EE 5 resources were different and more useful than the XML version turned into annotations.