SeamFramework.orgCommunity Documentation
Nós já vimos a forma como o modelo de injeção de dependências da Web Beans permite sobrescrever a implementação da API em tempo de implantação. Por exemplo, o seguinte Bean Web corporativo fornece uma implementação da API PaymentProcessor
em produção:
@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
Pode receber uma instância de StagingCreditCardPaymentProcessor
.
Infelizmente, existem várias armadilhas que facilmente podemos cair:
the higher-priority Web Bean may not implement all the API types of the Web Bean that it attempts to override,
the higher-priority Web Bean may not declare all the binding types of the Web Bean that it attempts to override,
the higher-priority Web Bean might not have the same name as the Web Bean that it attempts to override, or
the Web Bean that it attempts to override might declare a producer method, disposal method or observer method.
Em cada um destes casos, o Web Bean que tentamos sobrescrever ainda podia ser chamado em tempo de execução. Portanto, a sobrescrita é algo propensa a erros de desenvolvimento.
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:
ser uma subclasse direta do Web Bean que sobrescreve, e
be a simple Web Bean if the Web Bean it overrides is a simple Web Bean or an enterprise Web Bean if the Web Bean it overrides is an enterprise Web Bean, and
será anotada @Specializes
.
@Stateless @Staging @Specializes
public class StagingCreditCardPaymentProcessor
extends CreditCardPaymentProcessor {
...
}
Nós dizemos que a alta prioridade na Web Bean specializa sua superclasse.
Quando a especialização é utilizada:
the binding types of the superclass are automatically inherited by the Web Bean annotated @Specializes
, and
the Web Bean name of the superclass is automatically inherited by the Web Bean annotated @Specializes
, and
métodos produtores, métodos de eliminação e métodos observadores declarados pela superclasse são chamados sobre uma instância do Web Bean anotado com @Specializes
.
Em nosso exemplo, o tipo de ligação (binding type) @CreditCard
do CreditCardPaymentProcessor
é herdado por StagingCreditCardPaymentProcessor
.
Além disso, o gerenciador do Web Bean irá validar que:
all API types of the superclass are API types of the Web Bean annotated @Specializes
(all local interfaces of the superclass enterprise bean are also local interfaces of the subclass),
o tipo de implantação do Web Bean anotado com @Specializes
tem uma precedência maior do que o tipo de implantação da superclasse, e
não há outro Web Bean ativado que também especializa a superclasse.
Se qualquer uma dessas condições são violadas, o gerenciador do Web Bean lança uma excepção em tempo de inicialização.
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.