Identify correct and incorrect statements or examples about interceptors, including implementing an interceptor class, the lifecycle of interceptor instances, @AroundInvoke methods, invocation order, exception handling, lifecycle callback methods, default and method level interceptors, and specifying interceptors in the deployment descriptor.

[Note]
  • [EJB_3.0_CORE] 12.1; 12.2; 12.3; 12.3.1; 12.3.2; 12.4; 12.6; 12.7; 12.8; 12.8.1; 12.8.2; 12.8.2.1

Interceptors are used to interpose on business method invocations and lifecycle events that occur on an enterprise bean instance.

An interceptor method may be defined on an enterprise bean class or on an interceptor class associated with the bean. An interceptor class is a class - distinct from the bean class itself - whose methods are invoked in response to business method invocations and/or lifecycle events on the bean.

Any number of interceptor classes may be defined for a bean class.

It is possible to carry state across multiple interceptor method invocations for a single business method invocation or lifecycle callback event for a bean in the context data of the InvocationContext object.

An interceptor class must have a public no-arg constructor.

The programming restrictions that apply to enterprise bean components apply to interceptors as well. See here: Identify correct and incorrect statements or examples about EJB programming restrictions.

Interceptor Life Cycle (lifecycle of interceptor instances)

The lifecycle of an interceptor instance is the same as that of the bean instance with which it is associated. When the bean instance is created, interceptor instances are created for each interceptor class defined for the bean. These interceptor instances are destroyed when the bean instance is removed. In the case of interceptors associated with stateful session beans, the interceptor instances are passivated upon bean instance passivation, and activated when the bean instance is activated.

Both the interceptor instance and the bean instance are created or activated before any of the respective PostConstruct or PostActivate callbacks are invoked. Any PreDestroy and PrePassivate callbacks are invoked before the respective destruction or passivation of either the bean instance or interceptor instance.

An interceptor instance may hold state. An interceptor instance may be the target of dependency injection. Dependency injection is performed when the interceptor instance is created, using the naming context of the associated enterprise bean. The PostConstruct interceptor callback method is invoked after this dependency injection has taken place on both the interceptor instances and the bean instance.

Interceptors can invoke JNDI, JDBC, JMS, other enterprise beans, and the EntityManager.

The interceptors for a bean share the enterprise naming context of the bean for whose methods and lifecycle events they are invoked. Annotations and/or XML deployment descriptor elements for dependency injection or for direct JNDI lookup refer to this shared naming context.

The EJBContext object may be injected into an interceptor class. The interceptor may use the lookup method of the EJBContext interface to access the bean's JNDI naming context.

The use of an extended persistence context is only supported for interceptors that are associated with stateful session beans.

Business Method Interceptors (@AroundInvoke methods)

Interceptor methods may be defined for business methods of sessions beans and for the message listener methods of message-driven beans. Business method interceptor methods are denoted by the AroundInvoke annotation or around-invoke deployment descriptor element.

AroundInvoke methods may be defined on superclasses of the bean class or interceptor classes. However, only one AroundInvoke method may be present on a given class. An AroundInvoke method cannot be a business method of the bean.

AroundInvoke methods can have public, private, protected, or package level access. An AroundInvoke method must not be declared as final or static.

AroundInvoke methods have the following signature:


Object <METHOD>(InvocationContext) throws Exception
					
					

An AroundInvoke method can invoke any component or resource that a business method can.

Business method interceptor method invocations occur within the same transaction and security context as the business method for which they are invoked.

Business method interceptor methods may be defined to apply to business methods individually, rather than to all the business methods of the bean class.

Multiple Business Method Interceptor Methods (invocation order)

If multiple interceptor methods are defined for a bean, the following rules governing their invocation order apply. The deployment descriptor may be used to override the interceptor invocation order specified in annotations.

  1. Default interceptors, if any, are invoked first. Default interceptors can only be specified in the deployment descriptor. Default interceptors are invoked in the order of their specification in the deployment descriptor.

  2. If there are any interceptor classes defined on the bean class, the interceptor methods defined by those interceptor classes are invoked before any interceptor methods defined on the bean class itself.

  3. The AroundInvoke methods defined on those interceptor classes are invoked in the same order as the specification of the interceptor classes in the Interceptors annotation.

  4. If an interceptor class itself has superclasses, the interceptor methods defined by the interceptor class's superclasses are invoked before the interceptor method defined by the interceptor class, most general superclass first.

  5. After the interceptor methods defined on interceptor classes have been invoked, then, in order:

    1. If any method-level interceptors are defined for the business method that is to be invoked, the AroundInvoke methods defined on those interceptor classes are invoked in the same order as the specification of those interceptor classes in the Interceptors annotation applied to that business method. ZZZZ (See Section 12.7 for the description of method-level interceptors).

    2. If a bean class has superclasses, any AroundInvoke methods defined on those superclasses are invoked, most general superclass first.

    3. The AroundInvoke method, if any, on the bean class itself is invoked.

  6. If an AroundInvoke method is overridden by another method (regardless of whether that method is itself an AroundInvoke method), it will not be invoked.

The InvocationContext object provides metadata that enables interceptor methods to control the behavior of the invocation chain, including whether the next method in the chain is invoked and the values of its parameters and result.

Exceptions (exception handling)

Business method interceptor methods may throw runtime exceptions or application exceptions that are allowed in the throws clause of the business method.

AroundInvoke methods are allowed to catch and suppress exceptions and recover by calling proceed(). AroundInvoke methods are allowed to throw runtime exceptions or any checked exceptions that the business method allows within its throws clause.

AroundInvoke methods run in the same Java call stack as the bean business method. InvocationContext.proceed() will throw the same exception as any thrown by the business method unless an interceptor further down the Java call stack has caught it and thrown a different exception. Exceptions and initialization and/or cleanup operations should typically be handled in try/catch/finally blocks around the proceed() method.

AroundInvoke methods can mark the transaction for rollback by throwing a runtime exception or by calling the EJBContext setRollbackOnly() method. AroundInvoke methods may cause this rollback before or after InvocationContext.proceed() is called.

If a system exception escapes the interceptor chain the bean instance and any associated interceptor instances are discarded. The PreDestroy callbacks are not invoked in this case: the interceptor methods in the chain should perform any necessary clean-up operations as the interceptor chain unwinds.

Interceptors for LifeCycle Event Callbacks (lifecycle callback methods)

Lifecycle callback interceptor methods may be defined for session beans and message driven beans.

Interceptor methods for lifecycle event callbacks can be defined on an interceptor class and/or directly on the bean class. The PostConstruct, PreDestroy, PostActivate, and PrePassivate annotations are used to define an interceptor method for a lifecycle callback event. If the deployment descriptor is used to define interceptors, the post-construct, pre-destroy, post-activate, and pre-passivate elements are used.

Lifecycle callback interceptor methods and business method interceptor methods may be defined on the same interceptor class.

Lifecycle callback interceptor methods are invoked in an unspecified transaction and security context.

Lifecycle callback interceptor methods may be defined on superclasses of the bean class or interceptor classes. However, a given class may not have more than one lifecycle callback interceptor method for the same lifecycle event. Any subset or combination of lifecycle callback annotations may be specified on a given class.

A single lifecycle callback interceptor method may be used to interpose on multiple callback events (e.g., PostConstruct and PostActivate).

Lifecycle callback interceptor methods defined on an interceptor class have the following signature:


void <METHOD> (InvocationContext)
					
					

Lifecycle callback interceptor methods defined on a bean class have the following signature:


void <METHOD>()
					
					

Lifecycle callback interceptor methods can have public, private, protected, or package level access. A lifecycle callback interceptor method must not be declared as final or static.

Examples:

@Stateful 
public class ShoppingCartBean implements ShoppingCart {
	private float total;
	private Vector productCodes;
	public int someShoppingMethod() {...};
	...
	@PreDestroy 
	void endShoppingCart() {...};
}
					

public class MyInterceptor {

	@PostConstruct
	public void someMethod(InvocationContext ctx) {
		...
		ctx.proceed();
		...
	}

	@PreDestroy
	public void anotherMethod(InvocationContext ctx) {
		...
		ctx.proceed();
		...
	}
}
					

Default Interceptors

Default interceptors may be defined to apply to all the components within the ejb-jar. The deployment descriptor is used to define default interceptors and their relative ordering.

Default interceptors are automatically applied to all components defined in the ejb-jar. The ExcludeDefaultInterceptors annotation or exclude-default-interceptors deployment descriptor element is used to exclude the invocation of default interceptors for a bean.

The default interceptors are invoked BEFORE ANY OTHER interceptors for a bean. The interceptor-order deployment descriptor element may be used to specify alternative orderings.

Method-level Interceptors

A business method interceptor method may be defined to apply to a specific business method invocation, rather than to all of the business methods of the bean class.

NOTE. Method-level interceptor are used to specify business method interceptor methods. If an interceptor class that is used as a method-level interceptor defines lifecycle callback interceptor methods, those lifecycle callback interceptor methods are not invoked.

Method-specific business method interceptors can be defined by applying the Interceptors annotation to the method for which the interceptors are to be invoked, or by means of the interceptor-binding deployment descriptor element. If more than one method-level interceptor is defined for a business method, the interceptors are invoked in the order specified. Method-level business method interceptors are invoked in addition to any default interceptors and interceptors defined for the bean class (and its superclasses). The deployment descriptor may be used to override this ordering.

The same interceptor may be applied to more than one method of the bean class:

@Stateless
public class MyBean ... {
	public void notIntercepted() {}
	
	@Interceptors(org.acme.MyInterceptor.class)
	public void someMethod() {
		...
	}
	
	@Interceptors(org.acme.MyInterceptor.class)
	public void anotherMethod() {
		...
	}
}					
					

The applicability of a method-level interceptor to more than one business method of a bean does not affect the relationship between the interceptor instance and the bean class - only a SINGLE instance of the interceptor class is created PER BEAN instance.

The ExcludeDefaultInterceptors annotation or exclude-default-interceptors deployment descriptor element, when applied to a business method, is used to exclude the invocation of default interceptors for that method. The ExcludeClassInterceptors annotation or exclude-class-interceptors deployment descriptor element is used similarly to exclude the invocation of the class-level interceptors.

In the following example, if there are no default interceptors, only the interceptor MyInterceptor will be invoked when someMethod is called:

@Stateless
@Interceptors(org.acme.AnotherInterceptor.class)
public class MyBean ... {
	...
	@Interceptors(org.acme.MyInterceptor.class)
	@ExcludeClassInterceptors
	public void someMethod() {
		...
	}
}
					

If default interceptors have also been defined for the bean class, they can be excluded for the specific method by applying the ExcludeDefaultInterceptors annotation on the method:

@Stateless
@Interceptors(org.acme.AnotherInterceptor.class)
public class MyBean ... {
	...
	@ExcludeDefaultInterceptors
	@ExcludeClassInterceptors
	@Interceptors(org.acme.MyInterceptor.class)
	public void someMethod() {
		...
	}
}
					

Specification of Interceptors in the Deployment Descriptor

The deployment descriptor can be used as an alternative to metadata annotations to specify interceptors and their binding to enterprise beans or to override the invocation order of interceptors as specified in annotations.

The interceptor deployment descriptor element is used to specify the interceptor methods of an interceptor class. The interceptor methods are specified by using the around-invoke, pre-construct, post-destroy, pre-passivate, and post-activate elements.

At most ONE method of a given interceptor class can be designated as an around-invoke method, a pre-construct method, a post-destroy method, a pre-passivate method, or a post-activate method, regardless of whether the deployment descriptor is used to define interceptors or whether some combination of annotations and deployment descriptor elements is used.

The interceptor-binding element is used to specify the binding of interceptor classes to enterprise beans and their business methods. The subelements of the interceptor-binding element are as follows:

Interceptors bound to all classes using the wildcard syntax "*" are default interceptors for the components in the ejb-jar. In addition, interceptors may be bound at the level of the bean class (class-level interceptors) or business methods of the class (method-level interceptors).

The binding of interceptors to classes is additive. If interceptors are bound at the class-level and/or default-level as well as at the method-level, both class-level and/or default-level as well as method-level interceptors will apply. The deployment descriptor may be used to augment the interceptors and interceptor methods defined by means of annotations. When the deployment descriptor is used to augment the interceptors specified in annotations, the interceptor methods specified in the deployment descriptor will be invoked after those specified in annotations. The interceptor-order deployment descriptor element may be used to override this ordering.

The exclude-default-interceptors element disables default interceptors for the level at which it is specified and lower. That is, exclude-default-interceptors when applied at the class-level disables the application of default-interceptors for all methods of the class. The exclude-class-interceptors element applied to a method, disables the application of class-level interceptors for the given method. Explicitly listing an excluded higher-level interceptor at a lower level causes it to be applied at that level and below.

Examples of the usage of the interceptor-binding syntax are given below.

Style 1: The following interceptors apply to all components in the ejb-jar as default interceptors. They will be invoked in the order specified.


<interceptor-binding>
	<ejb-name>*</ejb-name>
	<interceptor-class>org.acme.MyDefaultIC</interceptor-class>
	<interceptor-class>org.acme.MyDefaultIC2</interceptor-class>
</interceptor-binding>
						
					

Style 2: The following interceptors are the class-level interceptors of the EmployeeService bean. They will be invoked in the order specified after any default interceptors.


<interceptor-binding>
	<ejb-name>EmployeeService</ejb-name>
	<interceptor-class>org.acme.MyIC</interceptor-class>
	<interceptor-class>org.acme.MyIC2</interceptor-class>
</interceptor-binding>
						
					

Style 3: The following interceptors apply to all the myMethod methods of the EmployeeService bean. They will be invoked in the order specified AFTER any default interceptors and class-level interceptors.


<interceptor-binding>
	<ejb-name>EmployeeService</ejb-name>
	<interceptor-class>org.acme.MyIC</interceptor-class>
	<interceptor-class>org.acme.MyIC2</interceptor-class>
	<method-name>myMethod</method-name>
</interceptor-binding>
						
					

Style 4: The following interceptor element refers to the myMethod(String firstName, String LastName) method of the EmployeeService bean.


<interceptor-binding>
	<ejb-name>EmployeeService</ejb-name>
	<interceptor-class>org.acme.MyIC</interceptor-class>
	<method-name>myMethod</method-name>
	<method-params>
		<method-param>java.lang.String</method-param>
		<method-param>java.lang.String</method-param>
	</method-params>
</interceptor-binding>
						
					

The following example illustrates the total ordering of interceptors using the interceptor-order element:


<interceptor-binding>
	<ejb-name>EmployeeService</ejb-name>
	<interceptor-order>
		<interceptor-class>org.acme.MyIC</interceptor-class>
		<interceptor-class>org.acme.MyDefaultIC</interceptor-class>
		<interceptor-class>org.acme.MyDefaultIC2</interceptor-class>
		<interceptor-class>org.acme.MyIC2</interceptor-class>
	</interceptor-order>
</interceptor-binding>
					
					

Professional hosting     Belorussian informational portal         Free SCWCD 1.4 Study Guide     Free SCDJWS 1.4 Study Guide     SCDJWS 1.4 Quiz     Free IBM Certified Associate Developer Study Guide     IBM Test 000-287. Enterprise Application Development with IBM WebSphere Studio, V5.0 Study Guide     Free Mock Exam Engine