[As we continue with this series, we will refer to some content and examples from the CDI 2.x specification].
The CDI specification allows developers the flexibility to create new types that are within the scopes of the bean type declaration.
In this example we will examine and learn how easy it is to create custom CDI annotations for defining:
- New qualifier types.
- New Stereotypes.
Defining new qualifier types.
A qualifier type is a Java annotation defined as @Retention(RUNTIME)
. Typically a qualifier type is defined as @Target({METHOD, FIELD, PARAMETER, TYPE})
.
Defining a qualifier type may be declared by specifying the @javax.inject.Qualifier
meta-annotation.
In our example, we've created 2 service-defined qualifier types, @Jabbawockee
and @LesTwins
qualifiers.
@Qualifier
@Documented
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
public @interface Jabbawockee {
}
@Qualifier
@Documented
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
public @interface LesTwins {
}
And a bean is qualified by annotating the bean class or producer method or field with the qualifier type.
@Jabbawockee
public class JabbawockeeService implements Service {
public void doWork() {
System.out.println("Jabbawockee doing the work.");
}
}
Stereotypes
The JavaEE specification specifies stereotypes as:
A stereotype is a kind of annotation, applied to a bean, that incorporates other annotations. Stereotypes can be particularly useful in large applications in which
you have a number of beans that perform similar functions.A well-known stereotypes, known by Enterprise Java Developers, are from Spring Framework:
@Component
,@Service
and@Repository
stereotypes.
A stereotype is an annotation, annotated @Stereotype
(@javax.enterprise.inject.Stereotype
), that packages several other annotations. For instance, to recreate the 3 stereotypes from Spring Framework into your JavaEE application:
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
@Documented
@Named
public @interface Component {}
Note that our Component
stereotype has been declared with an empty @Named
annotation, which specifies that every bean with the stereotype has a defaulted name when a name is not explicitly specified by the bean. A @Named
qualifier declared by a stereotype is not added to the qualifiers of a bean with the stereotype.
If a stereotype declares a non-empty @Named
annotation, the container automatically detects the problem and treats it as a definition error.
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
@Component //Note that Spring specifies that this annotation is a specialization of Component annotation.
public @interface Service {}
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Repository {}
Stereotype can be specified with interceptor bindings by annotating the stereotype with interceptor binding types. For example, to have a transactional business service, we can annotate our Service
stereotype with @Transactional
.
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
@Transactional
@Component
public @interface Service {}
Also, the default scope of a stereotype is defined by annotating the stereotype with a scope type. A stereotype may declare at most one scope. If a stereotype declares more than one scope, the container automatically detects the problem and treats it as a definition error.
For example, in our Controller
stereotype, we may specify to have a default @RequestScoped
scope type:
@RequestScoped
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
@Documented
@Named
public @interface Component {}
Built-in stereotype.
The CDI framework provides us with a built-in stereotype @javax.enterprise.inject.Model
which is intended for use with beans that define the model layer of an MVC web application architecture such as Jakarta Server Faces.
@Named
@RequestScoped
@Stereotype
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Model {}
In the next article, we will examine Producers (producer method and producer field), injecting using @Produces
and Decorators, using the @Decorator
annotation.
Top comments (0)