CHAPTER 2 EJB SESSION BEANS Arich client application(as shown in Figure 2-4)that runs on an end-user desktop machine and is used by the administrator for data entry purposes EJBContainer Session Bean Professional Client Session Bean Application Remote Calls JVM Session Bean JVM Application Server Figure2-4.Arich client using remote interfaces ofsession beans The SearchFacade session bean has both remote and local interfaces.as shown in Figure 2-5. <BusinessInterface> <BusinessInterface> SessionFacade SessionFacadeLocal <Session Bean> SessionFacadeBean Figure 2-5.The business interfaces of the SearchFacade session bean and awi tfor the SearchFacade re mote T earch() trepresents the type the wine,and it ret ns a list of wines that match the wine type criteria Listing 2-2.SearchFacade.java package com.ap ss.ejb.chapter02; import javax.ejb.Remote; PRemote public interface SearchFacade{ List wineSearch(String wineType); 2 30
s 30 • A rich client application (as shown in Figure 2-4) that runs on an end-user desktop machine and is used by the administrator for data entry purposes The SearchFacade session bean has both remote and local interfaces, as shown in Figure 2-5. Listing 2-2 shows the code snippet for the SearchFacade remote business interface with an @Remote annotation and a wineSearch() method declaration. The wineSearch() method takes one parameter that represents the type of the wine, and it returns a list of wines that match the wine type criteria. Listing 2-2. SearchFacade.java package com.apress.ejb.chapter02; import java.util.List; import javax.ejb.Remote; @Remote public interface SearchFacade { List wineSearch(String wineType); } Figure 2-4. A rich client using remote interfaces of session beans Figure 2-5. The business interfaces of the SearchFacade session bean
CHAPTER 2 EJB SESSION BEANS Listing 2-3 shows the code snippet for the SearchFacade local business interface with an @Local annotation and a wineSearch()method declaration. Listing2-3.SearchFacadeLocal.java package com.apress.ejb.chaptero2; import java.util.List; import javax.ejb.Local; eLocal Business Methods mene in the bean methods declared in the remoteo hey are matched up .Oth t they have e The se rchFacade b nethod winesearch()which has been declared in both and local business interfaces.The wines arch()method ret ursa static wines list based on the type of wine.Listing 2-4 shows the implementation for wineSearch(). Listing 2-4.SearchFacadeBean.java import iava.util.List: import javax.ejb.Stateless; @Stateless(name="SearchFacade") public class SearchFacadeBean implements SearchFacade,SearchFacadeLocal ub1cSeacFacadee else if (wineTy als("White")){ wineList.add("Chardo nnay"): return wineList; } 31
Chapter 2 ■ EJB Session Beans 31 Listing 2-3 shows the code snippet for the SearchFacade local business interface with an @Local annotation and a wineSearch() method declaration. Listing 2-3. SearchFacadeLocal.java package com.apress.ejb.chapter02; import java.util.List; import javax.ejb.Local; @Local public interface SearchFacadeLocal { List wineSearch(String wineType); } Business Methods The methods implemented in the bean class must correspond to the business methods declared in the remote or local business interfaces. They are matched up based on the convention that they have the same name and method signature. Other methods in the bean class that do not have the corresponding declaration in the business interfaces will be private to the bean class methods. The SearchFacade bean implements one method, wineSearch(), which has been declared in both remote and local business interfaces. The wineSearch() method returns a static wines list based on the type of wine. Listing 2-4 shows the implementation for wineSearch(). Listing 2-4. SearchFacadeBean.java package com.apress.ejb.chapter02; import java.util.ArrayList; import java.util.List; import javax.ejb.Stateless; @Stateless(name="SearchFacade") public class SearchFacadeBean implements SearchFacade, SearchFacadeLocal { public SearchFacadeBean() { } public List wineSearch(String wineType) { List wineList = new ArrayList(); if (wineType.equals("Red")) { wineList.add("Bordeaux"); wineList.add("Merlot"); wineList.add("Pinot Noir"); } else if (wineType.equals("White")) { wineList.add("Chardonnay"); } return wineList; } }
CHAPTER 2 EJB SESSION BEANS Asynchronous Business Methods Asynchronous methods immediately return to the caller without waiting for the method execution to complete. Asynchronous methods are typically used for processor intensive or long-running,background tasks,such as printing a document or sending a large email. Starting with EJB 3.1,a session bean can declare that one or more of its methods can be executed asynchronously.When a session bean client invokes an asynchronous method,the container immediately returns the control to the client.This allows the client to perform tasks in parallel while the business method completes its execution on a separate thread.For example,clients can use this functionality to show the progress of a long running task using a progress bar An is defined by annotaingabusi ess n ethod with javax.ejb.As annotation.An eAsynchronous annotation at the class level ma sah ess metnods ous met hAggnhrenethervoidc the session plication chro ous methods defined on a bean class should have the following signature turn Futur public void <METHOD>(Object) or public java.util.concurrent.Future<V><METHOD>(Object)throws <APPLICATION-EXCEPTION> Session bean clients invoke asynchronous methods in the same way they invoke synchronous methods.If an asynchronous method has been defined to return a result,the client immediately receives an instance of Future<V> interface.A client can use this instance for any of the following operations: 。 Retrieving the final result set using the get()method.Since this method call blocks syn until a result is returned or an exception is thrown,typically it is not called Checking the status of the asynchronous method using the isDone()method mply set s a state flag that can be odwithinthenningnehod Checking ifthe method invocation was cancelled using isCancelled()method Checking for exceptions Note Session bean methods that are exposed as web services can't be asynchronous. If an asynchronous method returns a result,it must return that result using the javax.ejb.AsyncResultV> convenience wrapper object.Note that this object is not actually returned to the client,but is intercepted by the EJB container and unwrapped to service method calls on the FutureV>object that was actually returned to the client when the client invoked the method 必
Chapter 2 ■ EJB Session Beans 32 Asynchronous Business Methods Asynchronous methods immediately return to the caller without waiting for the method execution to complete. Asynchronous methods are typically used for processor intensive or long-running, background tasks, such as printing a document or sending a large email. Starting with EJB 3.1, a session bean can declare that one or more of its methods can be executed asynchronously. When a session bean client invokes an asynchronous method, the container immediately returns the control to the client. This allows the client to perform tasks in parallel while the business method completes its execution on a separate thread. For example, clients can use this functionality to show the progress of a long running task using a progress bar. An asynchronous method is defined by annotating a business method with javax.ejb.Asynchronous annotation. An @Asynchronous annotation at the class level marks all the business methods of the session bean as asynchronous. An asynchronous method must return either void or an implementation of the java.lang.concurrent.Future<V> interface. Asynchronous methods that return void cannot throw application exceptions. Application exceptions can only be thrown by asynchronous methods that return Future<V>. Asynchronous methods defined on a bean class should have the following signature: public void <METHOD>(Object) or public java.util.concurrent.Future<V> <METHOD>(Object) throws <APPLICATION-EXCEPTION> Session bean clients invoke asynchronous methods in the same way they invoke synchronous methods. If an asynchronous method has been defined to return a result, the client immediately receives an instance of Future<V> interface. A client can use this instance for any of the following operations: • Retrieving the final result set using the get() method. Since this method call blocks synchronously until a result is returned or an exception is thrown, typically it is not called until isDone() returns true. • Checking the status of the asynchronous method using the isDone() method • Cancelling the method invocation using cancel(boolean) method. Calling cancel() does not interrupt the thread, it simply sets a state flag that can be checked within the running method so that it may gracefully interrupt its execution and return. • Checking if the method invocation was cancelled using isCancelled() method • Checking for exceptions ■ Note Session bean methods that are exposed as web services can’t be asynchronous. If an asynchronous method returns a result, it must return that result using the javax.ejb.AsyncResult<V> convenience wrapper object. Note that this object is not actually returned to the client, but is intercepted by the EJB container and unwrapped to service method calls on the Future<V> object that was actually returned to the client when the client invoked the method
CHAPTER 2 EJB SESSION BEANS Dependency Injection ming de esign pattern.In this section we wil type sof re es into stateless session be s.Typically in orde s the ethods in the auire one or m oes of res es.Theques rces can he other session beans.data sou ce or message queues Managed heans can he e injected into session beans using Contexts and Dependency Injection(CDD). The resources that the stateless session bean is trying to use can be injected using annotations or deployment descriptors.Resources can be acquired by annotation of instance variables or annotation of the setter methods. Listing 2-5 shows an example of setter and instance variable-based injection ofmyDb,which represents the data source. Listing 2-5.Data Source Injection eResource DataSource myDb; 1/Or eResource public void setMyDb(DataSource myDb){ this.myDb myDb; You'll typically use the setter injections to preconfigure or initialize properties of the injected resource. Lifecycle Callback Methods There will be certain instan or use cases in which the application using session beans requires fin -gra ned i cle events n,remov nd on.P acade se da or example,the Searc when iti ht need t e co thod c an be nod in the n that h annotations.The ElB container calls these methods at the a ate stages of the bean's lifecvcle (be and destruction). Following are two such callbacks for stateless session beans: PostConstruct:Denoted with the ePostConstruct annotation.Methods on the bean class that use a specific signature,as described below,can be marked with this annotation. PreDestroy:Denoted with the @PreDestroy annotation.Again,any method in the bean class with a specific signature,as described below,can be marked with this annotation. Callback methods defined on a bean class should have the following signature: void <METHOD>() Callback methods can also be defined on a bean's listener class;these methods should have the following signature: void <METHOD>(Object) 33
Chapter 2 ■ EJB Session Beans 33 Dependency Injection In Chapter 1, we introduced the concept of dependency injection as a programming design pattern. In this section, we will take a cursory look into using dependency injection in stateless session beans. Dependency injection is discussed in detail in Chapter 10. EJB containers provide the facilities to inject various types of resources into stateless session beans. Typically, in order to perform user tasks or process requests from client applications, the business methods in the session bean require one or more types of resources. These resources can be other session beans, data sources, or message queues. Managed beans can be injected into session beans using Contexts and Dependency Injection (CDI). The resources that the stateless session bean is trying to use can be injected using annotations or deployment descriptors. Resources can be acquired by annotation of instance variables or annotation of the setter methods. Listing 2-5 shows an example of setter and instance variable–based injection of myDb, which represents the data source. Listing 2-5. Data Source Injection @Resource DataSource myDb; // or @Resource public void setMyDb(DataSource myDb) { this.myDb = myDb; } You’ll typically use the setter injections to preconfigure or initialize properties of the injected resource. Lifecycle Callback Methods There will be certain instances or use cases in which the application using session beans requires fine-grained control over lifecycle events like its own 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 lifecycle 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 lifecycle (bean creation and destruction). Following are two such callbacks for stateless session beans: • PostConstruct: Denoted with the @PostConstruct annotation. Methods on the bean class that use a specific signature, as described below, can be marked with this annotation. • PreDestroy: Denoted with the @PreDestroy annotation. Again, any method in the bean class with a specific signature, as described below, can be marked with this annotation. Callback methods defined on a bean class should have the following signature: void <METHOD>() Callback methods can also be defined on a bean’s listener class; these methods should have the following signature: void <METHOD>(Object)
CHAPTER 2 EJB SESSION BEANS where Object may be declared as the actual bear which is the ssed to the callback method a caack methods can have public.private.protected.or packase level accesAlfecycle cabac run time.Life method must not be declared as final or static. PostConstruct 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(), which 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 chapter,we will just use some hard-coded values that get populated into a HashMap,as shown in Listing 2-6. Listing 2-6.The PostConstruct Method ePostConstruct public void initializeCountryWineList(){ I∥countryMap is Hash countryMap.put( 'Austra "Sauvignon Blanc"); ap.pu ustra 1a Gren ner); countryMap.put("France","Bordeaux"); red bean instance from its and also to release any other resources. In the case of the SearchFacade session bean,we could add a PreDestroy callback method(destroyWineList()) into the SearchFacade bean,which would clear the country wine list whenever the bean gets destroyed.Ideally, during PreDestroy,we would close any resources that have been created with dependency injection;but in this chapter,we will just clear the HashMap that has the countries and wine list.Listing 2-7 shows the destroyWineList() code. Listing 2-7.The PreDestroy Method @PreDestroy public void destroyWineList(){ countryMap.clear(); Interceptors The EJB specification provides annotations called interceptors which allow you to interpose on a business method invocation to add your own wrapper code before and/or after the method is called.An interceptor method can be defined for session and message-driven beans(MDBs).We will show you the usage of interceptors in the session bean context. al application in which yo ld find a n Do some performance analysis to compute the time it takes to perform the task Do additional logging before or after the method invocation
Chapter 2 ■ EJB Session Beans 34 where Object may be declared as the actual bean type, which is the argument passed to the callback method at run time. Lifecycle callback methods can have public, private, protected, or package level access. A lifecycle callback method must not be declared as final or static. PostConstruct 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(), which 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 chapter, we will just use some hard-coded values that get populated into a HashMap, as shown in Listing 2-6. Listing 2-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, we could add a PreDestroy callback method (destroyWineList()) into the SearchFacade bean, which would clear the country wine list whenever the bean gets destroyed. Ideally, during PreDestroy, we would close any resources that have been created with dependency injection; but in this chapter, we will just clear the HashMap that has the countries and wine list. Listing 2-7 shows the destroyWineList() code. Listing 2-7. The PreDestroy Method @PreDestroy public void destroyWineList() { countryMap.clear(); } Interceptors The EJB specification provides annotations called interceptors, which allow you to interpose on a business method invocation to add your own wrapper code before and/or after the method is called. An interceptor method can be defined for session and message-driven beans (MDBs). We 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