29
v010424 EJB Patterns Enterprise Java EJB Patterns Source: http://java.sun.com/j2ee/blueprints/ patterns/index.html

Enterprise Java v010424EJB Patterns Source:

Embed Size (px)

Citation preview

Page 1: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

EJB Patterns

Source:

http://java.sun.com/j2ee/blueprints/patterns/index.html

Page 2: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Bimodal Data Access

• http://java.sun.com/blueprints/patterns/j2ee_patterns/fast_lane_reader/index.html

• Provide efficient read-only access to server object state while accounting for transactional updates

• Motivation– When more important to read objects efficiently than to

read their most current state

• Key Aspects– Implement direct read-only access to database in the

client

– Implement transactional updates in the EJB

Page 3: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Data Access Objects

• http://java.sun.com/blueprints/patterns/j2ee_patterns/data_access_object/index.html

• Description– encapsulate access to object storage away from

usage/representation

• Motivation– Allows one to implement the same business logic over

multiple forms of data storage forms.

• Key Aspects– Use in EJB and non-EJB clients

– Use of interface/dynamic implementation best

Page 4: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Front Component

• http://java.sun.com/j2ee/blueprints/patterns/front_component/index.html

• Description– Simplify interaction with a series of objects

• Motivation– Provide ease-of-use interface to well factored

application

• Key Aspects– Session Bean or Servlet managing workflow through

business methods

Page 5: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Model-View-Controller

• http://java.sun.com/blueprints/patterns/j2ee_patterns/model_view_controller/index.html

• Description– Decouples data presentation, representation, and

operations

• Motivation– Increase reuse

• Key Aspects– Model - manages state, notifies Views of change– View - render state– Control - updates state, selects Views

Page 6: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Page List

• http://java.sun.com/blueprints/patterns/j2ee_patterns/page_by_page_iterator/index.html

• Description– Traverse large collections more efficiently by accessing

elements in page increments

• Motivation– Only chunks of collection are retrieved when not all of

collection desired

• Key Aspects– Page List Access providing Client Access Pages

– Client Access providing clients single elements

Page 7: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Session Entity Façade

• Description– Provide a single API for collection of EJBs

• Motivation– Simplifies or focuses client interaction with application

• Key Aspects– Layer of Session Bean(s) hide application

implementation from Client’s view of system

Page 8: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Value Object

• http://java.sun.com/blueprints/patterns/j2ee_patterns/value_object/index.htmlDescription

– Provides bulk access to related information

• Motivation– Cut down on unnecessary overhead accessing

properties individually that are normally accessed together

• Key Aspects– Serializable structure passed between bean and client

Page 9: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Service Locator

• Factors– EJB clients repeatedly look up home interfaces using

JNDI

– Requires too much knowledge

– Can lead to inefficient design

• Solution– Develop a ServiceLocator object

• Abstract JNDI usage

• Simplify client interaction with the system

• Cache resources when possible

Page 10: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Service Locator (Cont)

• Implementation Notes– InitialContext lookup is slow

– InitialContext object may not be thread-safe

– EJBHome lookup is slow

– Bean’s Home object can be shared among threads

Page 11: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Implementationpackage corej2ee.project.ejb;

import corej2ee.project.ejb.ServiceLocatorException;

import java.util.*;

import javax.naming.*;

import java.rmi.RemoteException;

import javax.ejb.*;

import javax.rmi.PortableRemoteObject;

import java.io.*;

import java.util.Map;

import java.util.HashMap;

/**

* Basic service locator implementation that caches home references

* for clients

*/

Page 12: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava/**

* Basic service locator implementation that caches home references

* for clients

*/

public class ServiceLocator {

/**

* Singleton constructor

*

* @throws ServiceLocatorException

*/

private ServiceLocator() throws ServiceLocatorException{

try {

context = new InitialContext();

} catch (NamingException ne) {

throw new ServiceLocatorException(ne);

}

}

Page 13: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

/**

* Returns singleton instance

*

* @throws ServiceLocatorException

*/

public static ServiceLocator getInstance() throws ServiceLocatorException{

if (myServiceLocator == null) {

myServiceLocator = new corej2ee.project.ejb.ServiceLocator();

}

return myServiceLocator;

}

Page 14: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

/**

* Retrieves the EJBObject instance from a previosly serialized

* handle

*

* @param id serialized EJBObject handle

* @throws ServiceLocatorException

* @return EJBObject reference for handle

*/

public static EJBObject getService(String id)throws ServiceLocatorException{

if (id == null) {

return null;

}

try {

byte[] bytes = new String(id).getBytes();

InputStream io = new ByteArrayInputStream(bytes);

ObjectInputStream os = new ObjectInputStream(io);

javax.ejb.Handle handle = (javax.ejb.Handle) os.readObject();

return handle.getEJBObject();

} catch (Exception ex) {

throw new ServiceLocatorException(ex);

}

}

Page 15: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

/**

* Creates a serialized representation for an EJBObject so it can

* be re-created at a later time

* @param session EJBObject to create a handle for

* @throws ServiceLocatorException

* @return serialized handle for the EJBObject

*/

public static String getId(EJBObject session)throws ServiceLocatorException{

try {

javax.ejb.Handle handle = session.getHandle();

ByteArrayOutputStream fo = new ByteArrayOutputStream();

ObjectOutputStream so = new ObjectOutputStream(fo);

so.writeObject(handle);

so.flush();

so.close();

return new String(fo.toByteArray());

} catch (RemoteException ex) {

throw new ServiceLocatorException(ex);

} catch (IOException ex) {

throw new ServiceLocatorException(ex);

}

}

Page 16: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

/**

* Returns the home object for the specified JNDI name

*

* @param name JNDI name of the Home interface

* @param clazz Specific Home class

* @throws ServiceLocatorException

* @return Home stub

*/

public EJBHome getHome(String name, Class clazz)throws ServiceLocatorException{

try {

if(homeMap.containsKey(name)) {

System.out.println("Returning from cache");

return (EJBHome) homeMap.get(name);

}

Page 17: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

else {

Object objref=null;

System.out.println("Looking up home using initial context");

synchronized(context) {

objref = context.lookup(name);

}

EJBHome home = (EJBHome)PortableRemoteObject.narrow(objref, clazz);

homeMap.put(name, home);

return home;

}

} catch (NamingException ex) {

throw new ServiceLocatorException(ex);

}

}

private static ServiceLocator myServiceLocator; // singleton

private InitialContext context = null; // connection to naming service

private Map homeMap=new HashMap(); // stores already retrieved homes

}

Page 18: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Client Usage

try {

System.out.println("Using service locator");

ServiceLocator sl=ServiceLocator.getInstance();

TellerHome home=

(TellerHome) sl.getHome("TellerBean",corej2ee.project.ejb.TellerHome.class);

Teller teller = home.create();

Customer c=new Customer("Dan");

teller.addCustomer(c);

teller.remove();

System.out.println("Test completed");

}

catch(RemoteException re) {

……

Page 19: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Service Locator Summary

• Provides a simpler mechanism for clients to locate remote resources

• Improved performance obtained with context and home object caching

• Frequently implemented for other distributed objects– JMS Connection Factories– JMS Destinations; Topics and Queues

• Other implementation strategies possible. Concept is what is important

Page 20: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Business Delegate

• Factors– Presentation Tier makes distributed calls to Business Tier

components. Exposed to complexity– Performance implications if client makes too many remote calls– Tight coupling. Client needs to know lookup and access details

• Solution– Develop BusinessDelegate to abstract implementation details of

the business service– Client-Side business abstraction– May implement caching mechanism– Can retry when errors occur– Wrap Remote Exceptions as a business exception

Page 21: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Proxy Implementation Details

• Uses a ServiceLocator to locate the target business service

• Delegates business method calls to remote business service– May cache data to reduce the number of remote calls

made– Remote exceptions translated to application exceptions

for client

• May provide simpler interface to client– e.g. can hold state to simplify calling of remote

stateless session beans

Page 22: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Implementationpublic class TellerBusinessDelegate {

publicTellerBusinessDelegate() throws BusinessException{

try {

TellerHome home = (TellerHome)ServiceLocator.getInstance().getHome(

"TellerBean", homeClazz);

session = home.create();

}

catch (ServiceLocatorException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

catch (CreateException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

catch (RemoteException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

}

Page 23: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

public TellerBusinessDelegate(String id) throws BusinessException{

reconnect(id);

}

public String getID() throws BusinessException{

try {

return corej2ee.project.ejb.ServiceLocator.getId(session);

}

catch (Exception e) {

throw new corej2ee.project.ejb.BusinessException(e);

}

}

public void reconnect(String ID) throws BusinessException{

try {

session = (Teller)corej2ee.project.ejb.ServiceLocator.getService(ID);

}

catch (ServiceLocatorException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

}

Page 24: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

public void addCustomer(Customer c) throws BusinessException{

try {

session.addCustomer(c);

}

catch (java.rmi.RemoteException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

}

public void transfer(int to,int from,double amount) throws BusinessException{

try {

session.transfer(to, from, amount);

}

catch (java.rmi.RemoteException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

}

Page 25: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

public void removeCustomer(Customer c) throws BusinessException{

try {

session.removeCustomer(c);

}

catch (java.rmi.RemoteException ex) {

throw new corej2ee.project.ejb.BusinessException(ex);

}

}

public void close() {

if(session != null) {

try {

session.remove();

session=null;

}

catch(Exception e) {

}

}

}

Page 26: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

protected void finalize() {

close();

}

/**

* @link

* @shapeType PatternLink

* @pattern Business Delegate Proxy Strategy

* @supplierRole Uses

*/

/*# private BusinessException _businessException; */

private Teller session;

private Class homeClazz = TellerHome.class;

}

Page 27: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Client Programpackage corej2ee.project.ejb;

public class TellerClient {

public static void main(String[] argv){

try {

TellerBusinessDelegate teller=new TellerBusinessDelegate();

Customer c=new Customer("Dan");

teller.addCustomer(c);

c=new Customer("Cathy");

teller.addCustomer(c);

teller.close();

} catch (BusinessException ex) {

ex.printStackTrace();

}

}

}

Page 28: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Business Delegate Summary

• Further simplifies client access to remote business services

• Hides complexity– JNDI lookup

– Remote Exceptions

• Performance enhancements– Home, Initial Context, Remote object reference caching

– Business Data caching• Not in this case

• Consider a business delegate for the Shopping Cart Bean

– Could hold all items in the cart locally and skip remote call when the client asks for all items

Page 29: Enterprise Java v010424EJB Patterns Source:

v010424 EJB Patterns

EnterpriseJava

Other Sources

• http://developer.java.sun.com/developer/technicalArticles/J2EE/patterns