November 27, 2014
Hot Topics:

EJB 3 Session Beans

  • December 22, 2006
  • By Raghu R. Kodali, Jonathan R. Wetherbee, and Peter Zadrozny
  • Send Email »
  • More Articles »

Callback Methods

There will be certain instances or use cases in which the application using session beans requires fine-grained control over things like an object's creation, removal, and so on. For example, the SearchFacade session bean might need to perform some database initialization when it is created, or close some database connections when it is destroyed. The application can gain fine-grained control over the various stages of the bean life cycle via methods known as callback methods. A callback method can be any method in the session bean that has callback annotations. The EJB container calls these methods at the appropriate stages of the bean's life cycle (bean creation and destruction).

Following are two such callbacks for stateless session beans:

  • PostConstruct: Denoted with the @PostContruct annotation. Any method in the bean class can be marked with this annotation.
  • PreDestroy: Denoted with the @PreDestroy annotation. Again, any method in the bean class can be marked with this annotation.

PostContruct callbacks happen after a bean instance is instantiated in the EJB container. If the bean is using any dependency injection mechanisms for acquiring references to resources or other objects in its environment, PostConstruct will occur after injection is performed and before the first business method in the bean class is called.

In the case of the SearchFacade session bean, you could have a business method, wineSearchByCountry(), that would return the wine list for a particular country, and have a PostConstruct callback method, initializeCountryWineList(), that would initialize the country's wine list whenever the bean gets instantiated. Ideally, you would load the list from a back-end datastore; but in this article, you will just use some hard-coded values that get populated into a HashMap, as shown in Listing 6.

Listing 6. The PostConstruct Method

@PostConstruct

public void initializeCountryWineList()
{
   //countryMap is HashMap
   countryMap.put("Australia", "Sauvignon Blanc");
   countryMap.put("Australia", "Grenache");
   countryMap.put("France","Gewurztraminer");
   countryMap.put("France","Bordeaux");
}

The PreDestroy callback happens before the container destroys an unused or expired bean instance from its object pool. This callback can be used to close any connection pool that has been created with dependency injection, and also to release any other resources.

In the case of the SearchFacade session bean, you could add a PostConstruct callback method (destroyWineList()) into the SearchFacade bean, which would clear the country wine list whenever the bean gets destroyed. Ideally, during PostContruct, you would close any resources that have been created with dependency injection; but in this article, you will just clear the HashMap that has the countries and wine list. Listing 7 shows the destroyWineList() code.

Listing 7. The PreDestroy Method

@PreDestroy
public void destroyWineList()
   {
   countryMap.clear();
   }

Callback methods defined on a bean class should have the following signature:

public void <METHOD>()

Callback methods can also be defined on a bean's listener class; these methods should have the following signature:

public void <METHOD>(Object)

where Object may be declared as the actual bean type, which is the argument passed to the callback method at run time.

Interceptors

The EJB 3 specification provides annotations called interceptors, which allow you to intercept a business method invocation. An interceptor method can be defined for session and message-driven beans (MDBs). You will show you the usage of interceptors in the session bean context.

There are number of use cases for interceptors in a typical application, in which you would find a need to perform a certain task before or after the business method is invoked. For example, you may wish to do one of the following:[

  • Perform additional security checks before a critical business method that transfers more than $100,000 dollars
  • Do some performance analysis to compute the time it takes to perform the task
  • Do additional logging before or after the method invocation

You can either add an @AroundInvoke annotation on a particular method, or you can define an interceptor class whose methods are invoked before a business method is invoked in the bean class. An interceptor class is denoted by the @Interceptor annotation on the bean class with which it is associated. In the case of multiple interceptor classes, the @Interceptors annotation is used. Methods that are annotated with @AroundInvoke should have the following signature:

public Object <METHOD>(InvocationContext) throws Exception

The definition of InvocationContext is as follows:

package javax.ejb; 

   public interface InvocationContext {
   public Object getBean();
   public java.lang.reflect.Method getMethod();
   public Object[] getParameters();
   public void setParameters(Object[] params);
   public EJBContext getEJBContext();
   public java.util.Map getContextData();
   public Object proceed() throws Exception;
}

The following list describes the methods in the preceding code:

  • getBean() returns the instance of the bean on which the method was called.
  • getMethod() returns the method on the bean instance that was called.
  • getParameters() returns the parameters for the method call.
  • setParameters() modifies the parameters used for the method call.
  • getEJBContext() gives the interceptor methods access to the bean's EJBContext.
  • getContextData() allows values to be passed between interceptor methods in the same InvocationContext instance using the Map returned.
  • proceed() invokes the next interceptor, if there is one, or invokes the target bean method.

In the SearchFacade session bean, you can add an interceptor that logs the time taken to execute each business method when invoked by the client applications. Listing 8 shows a time log method that will print out the time taken to execute a business method. InvocationContext is used to get the name of bean class and the invoked method name. Before invoking the business method, current system time is captured and deducted from the system time after the business method is executed. Finally, the details are printed out to the console log using System.out.println.

Listing 8. The Interceptor Method

@AroundInvoke 

public Object TimerLog (InvocationContext ctx) throws Exception
   {
   String beanClassName = ctx.getClass().getName();
   String businessMethodName = ctx.getMethod().getName();
   String target = beanClassName + "." + businessMethodName ;
   long startTime = System.currentTimeMillis();
   System.out.println ("Invoking " + target);
      try {
         return ctx.proceed();
         }
      finally {
         System.out.println("Exiting " + target);
         long totalTime = System.currentTimeMillis() - startTime;
         System.out.println("Business method " + businessMethodName +
         "in " + beanClassName + "takes " + totalTime + "ms to execute");
      }

}

Stateful Session Beans

Similar to stateless session beans, stateful beans comprise a bean class and a business interface.

The Bean Class

A stateful session bean class is any standard Java class that has a class-level annotation of @Stateful. If deployment descriptors are used instead of annotations, the bean class should be denoted as a stateful session bean. In the case of mixed mode, in which you are using annotations and deployment descriptors, the @Stateful annotation must be specified if any other class-level or member-level annotations are specified in the class.

To illustrate a stateful session bean, you will create a ShoppingCart session bean that will keep track of the items added to a user's shopping cart and their respective quantities. In this article, you will use hard-coded values for the shopping cart to illustrate the state and conversation maintenance between the client and stateful session bean. Listing 9 shows the definition of a ShoppingCart session bean.

Listing 9. ShoppingCartBean.java

package com.apress.ejb3.chapter02; 

import javax.ejb.Stateful; 

@Stateful(name="ShoppingCart") 

public class ShoppingCartBean implements ShoppingCart,
   ShoppingCartLocal {
   public ShoppingCartBean() {
   }
}

There will be certain use cases in which the application wants to be notified by the EJB container before or after transactions take place, and then use these notifications to manage data and cache. A stateful session bean can receive this kind of notification by the EJB container when it implements the javax.ejb.SessionSynchronization interface. This is an optional feature. There are three different types of transaction notifications that the stateful session bean receives from the EJB container, as follows:

  • afterBegin: Indicates that a new transaction has begun
  • beforeCompletion: Indicates that the transaction is going to be committed
  • afterCompletion: Indicates that a transaction has been completed

For example, the ShoppingCart session bean could implement the javax.ejb.SessionSynchronization interface to get an afterCompletion notification, so that it can clear out the shopping cart cache.





Page 3 of 5



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel