SeamFramework.orgCommunity Documentation
Los interceptores son una forma potente de capturar y distinguir cuestiones que son ortogonales al tipo de sistema. Cualquier interceptor puede interceptar invocaciones de cualquier tipo de Java. Esto los hace perfectos para resolver cuestiones técnicas como la administración de transacción y la seguridad. Sin embargo, por naturaleza, los interceptores desconocen la semántica real de los eventos que interceptan. Por lo tanto, los interceptores no son una herramienta apropiada para distinguir cuestiones relacionadas con negocios.
En cambio, los decoradores interceptan invocaciones únicamente para una determinada interfaz de Java y por lo tanto, conocen toda la semántica asociada a la interfaz. Esto los hace una herramienta perfecta para representar algunas clases de cuestiones de negocios. También significa que los decoradores no tienen la generalidad de un interceptor. Los decoradores no pueden resolver problemas técnicos que atraviesan muchos tipos dispares.
Supongamos que tenemos una interfaz que representa cuentas:
public interface Account {
public BigDecimal getBalance();
public User getOwner();
public void withdraw(BigDecimal amount);
public void deposit(BigDecimal amount);
}
Varios Web Beans diferentes en nuestro sistema implementan la interfaz de Cuenta
. No obstante, tenemos un requisito legal que, para cualquier clase de cuenta, las transacciones grandes deben ser registradas por el sistema en un registro especial. Este es el trabajo perfecto para un decorador.
Un decorador es un Web Bean sencillo que implementa el tipo que decora y es anotado @Decorator
.
@Decorator
public abstract class LargeTransactionDecorator
implements Account {
@Decorates Account account;
@PersistenceContext EntityManager em;
public void withdraw(BigDecimal amount) {
account.withdraw(amount);
if ( amount.compareTo(LARGE_AMOUNT)
>0 ) {
em.persist( new LoggedWithdrawl(amount) );
}
}
public void deposit(BigDecimal amount);
account.deposit(amount);
if ( amount.compareTo(LARGE_AMOUNT)
>0 ) {
em.persist( new LoggedDeposit(amount) );
}
}
}
A diferencia de otros Web Beans sencillos, un decorador puede ser una clase abstracta. Si no hay nada especial que el decorador tenga que hacer para un método particular de la interfaz decorada, usted no necesita implementar ese método.
Todos los decoradores tienen un atributo de delegado. El tipo y los tipos de vinculación del atributo de delegado determinan los Web Beans a los que el decorador está vinculado. El tipo de atributo de delegado debe implementar o extender todas las interfaces ejecutadas por el decorador.
Este atributo de delegado especifica que el decorador está vinculado a los Web Beans que implementan Cuenta
:
@Decorates Account account;
Un atributo de delegado puede especificar una anotación de enlace. Luego el decorador sólo estará vinculado a los Web Beans con el mismo enlace.
@Decorates @Foreign Account account;
Un decorador está vinculado a cualquier Web Bean que:
tenga el tipo de atributo de delegado como un tipo API, y
tenga todos los tipos de vinculación declarados por el atributo de delegado.
El decorador puede invocar el atributo de delegado, el cual tiene casi el mismo efecto que llamar a InvocationContext.proceed()
desde un interceptor.
Necesitamos habilitar nuestro decorador en web-beans.xml
.
<Decorators>
<myapp:LargeTransactionDecorator/>
</Decorators
>
Esta declaración sirve para decoradores al igual que la declaración <Interceptores>
sirve para interceptores:
nos permite especificar un orden total para los decoradores en nuestro sistema, garantizando una conducta de determinación y
nos permite habilitar o inhabilitar las clases de decorador en el momento de implementación.
Los interceptores para un método son llamados antes de los decoradores que aplican a ese método.