SeamFramework.orgCommunity Documentation

Chapter 11. Specialization

11.1. Using specialization
11.2. Advantages of specialization

We've already seen how the Web Beans dependency injection model lets us override the implementation of an API at deployment time. For example, the following enterprise Web Bean provides an implementation of the API PaymentProcessor in production:

@CreditCard @Stateless

public class CreditCardPaymentProcessor 
        implements PaymentProcessor {

But in our staging environment, we override that implementation of PaymentProcessor with a different Web Bean:

@CreditCard @Stateless @Staging

public class StagingCreditCardPaymentProcessor 
        implements PaymentProcessor {

What we've tried to do with StagingCreditCardPaymentProcessor is to completely replace AsyncPaymentProcessor in a particular deployment of the system. In that deployment, the deployment type @Staging would have a higher priority than the default deployment type @Production, and therefore clients with the following injection point:

@CreditCard PaymentProcessor ccpp

Would receive an instance of StagingCreditCardPaymentProcessor.

Unfortunately, there are several traps we can easily fall into:

In each of these cases, the Web Bean that we tried to override could still be called at runtime. Therefore, overriding is somewhat prone to developer error.

Web Beans provides a special feature, called specialization, that helps the developer avoid these traps. Specialization looks a little esoteric at first, but it's easy to use in practice, and you'll really appreciate the extra security it provides.

Specialization is a feature that is specific to simple and enterprise Web Beans. To make use of specialization, the higher-priority Web Bean must:

@Stateless @Staging @Specializes

public class StagingCreditCardPaymentProcessor 
        extends CreditCardPaymentProcessor {

We say that the higher-priority Web Bean specializes its superclass.

When specialization is used:

In our example, the binding type @CreditCard of CreditCardPaymentProcessor is inherited by StagingCreditCardPaymentProcessor.

Furthermore, the Web Bean manager will validate that:

If any of these conditions are violated, the Web Bean manager throws an exception at initialization time.

Therefore, we can be certain that the superclass will never be called in any deployment of the system where the Web Bean annotated @Specializes is deployed and enabled.