Enterprise Java Development@TOPIC@
Interpose on contructor, EJB business and lifecycle methods
Interceptor lifecycle is same as the bean it interposes on (i.e., Stateless/Stateful)
EJB Interceptors may define AroundInvoke
callbacks for
business methods
MDB onMessage()
May throw runtime and application exceptions declared by business method
Interceptors may rollback the current transaction by
throwing a RuntimeException
calling setRollbackOnly()
on the EJBContext
@Stateless
public class ContactsEJB implements ContactsRemote {
@PersistenceContext(unitName="ejbinterceptor-contacts")
private EntityManager em;
@Override
public Contact createContact(Contact contact) throws InvalidParam {
logger.debug("createContact({})", contact);
em.persist(contact);
return contact;
}
import javax.interceptor.AroundConstruct;
public class LifecycleInterceptor {
@Resource
private EJBContext ejbCtx;
@AroundInvoke
public Object invoke(InvocationContext ctx) throws Exception {
logger.debug("*** Business Method: {}, caller={}", ctx.getMethod(), ejbCtx.getCallerPrincipal().getName());
Object response = ctx.proceed();
logger.debug("*** Response Object: {}", response);
return response;
}
Simple interceptor logs call and response
LifecycleInterceptor] (EJB default - 4) *** Business Method: public info.ejava.examples.ejb.interceptor.bo.Contact info.ejava.examples.ejb.interceptor.ejb.ContactsEJB.createContact(info.ejava.examples.ejb.interceptor.bo.Contact) throws info.ejava.examples.ejb.interceptor.ejb.InvalidParam, caller=anonymous ContactsEJB] (EJB default - 4) createContact(Contact [id=0, name=John Doe, normalizedName=null]) LifecycleInterceptor] (EJB default - 4) *** Response Object: Contact [id=1, name=John Doe, normalizedName=john doe]
Interceptor was able to identify what was being called and who was calling it
Interceptor could have implemented security constraints, validation, etc.
Information about the call intercepted
Methods to control behavior of invocation chain
public interface javax.interceptor.InvocationContext {
public abstract java.lang.Object getTarget();
public abstract java.lang.Object getTimer();
public abstract java.lang.reflect.Method getMethod();
public abstract java.lang.reflect.Constructor<?> getConstructor();
public abstract java.lang.Object[] getParameters();
public abstract void setParameters(java.lang.Object[]);
public abstract java.util.Map<java.lang.String, java.lang.Object> getContextData();
public abstract java.lang.Object proceed() throws java.lang.Exception;
}
All EJB Interceptors may define standard lifecycle callbacks
AroundConstruct
PostConstruct
PreDestory
Stateful EJB Interceptors
may define state callbacks
PrePassivate
PostActivate
may use an extended persistence context
EJB Interceptors may define AroundTimeout
for timer methods
May call InvocationContext.getTimer()
to get timed out timer
May not throw application exceptions
Three (3) ways:
EJB Deployment descriptor (ejb-jar.xml)
@Interceptors annotation
CDI Deployment descriptor (beans.xml)
<?xml version="1.0"?>
<ejb-jar ...
<assembly-descriptor>
<interceptor-binding>
<ejb-name>ContactsEJB</ejb-name>
<interceptor-class>
info.ejava.examples.ejb.interceptor.interceptors.LifecycleInterceptor
</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
</ejb-jar>
Decouples EJB and Interceptor classes
Assign to specific EJBs or globally
Assign to specific EJB methods or global to class
Can control order applied
//way 1 - class level
@Stateless
@Interceptors({ //global to EJB class
PreNormizedInterceptor.class,
ContactsNormalizerInterceptor.class,
PostNormizedInterceptor.class,
})
public class ContactsEJB implements ContactsRemote {
//way 2 - method level
@Stateless
public class ContactsEJB implements ContactsRemote {
@Override
@Interceptors({ //specific to individual EJB method
PreNormizedInterceptor.class,
ContactsNormalizerInterceptor.class,
PostNormizedInterceptor.class,
})
public Contact createContact(Contact contact) throws InvalidParam {
@Annotation near-equivalent to EJB deployment descriptor
Couples EJB class to Interceptor class
Cannot assign globally to all EJBs
Can assign to specific EJB methods or global to class
Can control order applied