Chapter 9. Stereotypes

According to the Web Beans specification:

In many systems, use of architectural patterns produces a set of recurring Web Bean roles. A stereotype allows a framework developer to identify such a role and declare some common metadata for Web Beans with that role in a central place.

A stereotype encapsulates any combination of:

  • a default deployment type,

  • a default scope type,

  • a restriction upon the Web Bean scope,

  • a requirement that the Web Bean implement or extend a certain type, and

  • a set of interceptor binding annotations.

A stereotype may also specify that all Web Beans with the stereotype have defaulted Web Bean names.

A Web Bean may declare zero, one or multiple stereotypes.

A stereotype is a Java annotation type. This stereotype identifies action classes in some MVC framework:

@Retention(RUNTIME)
@Target(TYPE)
@Stereotype
public @interface Action {}

We use the stereotype by applying the annotation to a Web Bean.

@Action 
public class LoginAction { ... }

9.1. Default scope and deployment type for a stereotype

A stereotype may specify a default scope and/or default deployment type for Web Beans with that stereotype. For example, if the deployment type @WebTier identifies Web Beans that should only be deployed when the system executes as a web application, we might specify the following defaults for action classes:

@Retention(RUNTIME)
@Target(TYPE)
@RequestScoped
@WebTier
@Stereotype
public @interface Action {}

Of course, a particular action may still override these defaults if necessary:

@Dependent @Mock @Action 
public class MockLoginAction { ... }

If we want to force all actions to a particular scope, we can do that too.

9.2. Restricting scope and type with a stereotype

Suppose that we wish to prevent actions from declaring certain scopes. Web Beans lets us explicitly specify the set of allowed scopes for Web Beans with a certain stereotype. For example:

@Retention(RUNTIME)
@Target(TYPE)
@RequestScoped
@WebTier
@Stereotype(supportedScopes=RequestScoped.class)
public @interface Action {}

If a particular action class attempts to specify a scope other than the Web Beans request scope, an exception will be thrown by the Web Bean manager at initialization time.

We can also force all Web Bean with a certain stereotype to implement an interface or extend a class:

@Retention(RUNTIME)
@Target(TYPE)
@RequestScoped
@WebTier
@Stereotype(requiredTypes=AbstractAction.class)
public @interface Action {}

If a particular action class does not extend the class AbstractAction, an exception will be thrown by the Web Bean manager at initialization time.

9.3. Interceptor bindings for stereotypes

A stereotype may specify a set of interceptor bindings to be inherited by all Web Beans with that stereotype.

@Retention(RUNTIME)
@Target(TYPE)
@RequestScoped
@Transactional(requiresNew=true)
@Secure
@WebTier
@Stereotype
public @interface Action {}

This helps us get technical concerns even further away from the business code!

9.4. Name defaulting with stereotypes

Finally, we can specify that all Web Beans with a certain stereotype have a Web Bean name, defaulted by the Web Bean manager. Actions are often referenced in JSP pages, so they're a perfect use case for this feature. All we need to do is add an empty @Named annotation:

@Retention(RUNTIME)
@Target(TYPE)
@RequestScoped
@Transactional(requiresNew=true)
@Secure
@Named
@WebTier
@Stereotype
public @interface Action {}

Now, LoginAction will have the name loginAction.

9.5. Standard stereotypes

We've already met two standard stereotypes defined by the Web Beans specification: @Interceptor and @Decorator.

Web Beans defines one further standard stereotype:

@Named 
@RequestScoped 
@Stereotype 
@Target({TYPE, METHOD}) 
@Retention(RUNTIME) 
public @interface Model {} 

This stereotype is intended for use with JSF. Instead of using JSF managed beans, just annotate a Web Bean @Model, and use it directly in your JSF page.