Title: Source:
1EJB Patterns
- Source
- http//java.sun.com/j2ee/blueprints/patterns/index
.html
2Bimodal Data Access
- http//java.sun.com/blueprints/patterns/j2ee_patte
rns/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
3Data Access Objects
- http//java.sun.com/blueprints/patterns/j2ee_patte
rns/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
4Front 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
5Model-View-Controller
- http//java.sun.com/blueprints/patterns/j2ee_patte
rns/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
6Page List
- http//java.sun.com/blueprints/patterns/j2ee_patte
rns/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
7Session 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 Clients view of system
8Value Object
- http//java.sun.com/blueprints/patterns/j2ee_patte
rns/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
9Service 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
10Service Locator (Cont)
- Implementation Notes
- InitialContext lookup is slow
- InitialContext object may not be thread-safe
- EJBHome lookup is slow
- Beans Home object can be shared among threads
11Implementation
package corej2ee.project.ejb import
corej2ee.project.ejb.ServiceLocatorException impo
rt 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 /
12/ Basic service locator implementation that
caches home references for clients / public
class ServiceLocator / Singleton
constructor _at_throws
ServiceLocatorException / private
ServiceLocator() throws ServiceLocatorException
try context new
InitialContext() catch
(NamingException ne) throw new
ServiceLocatorException(ne)
13 / Returns singleton instance
_at_throws ServiceLocatorException /
public static ServiceLocator getInstance() throws
ServiceLocatorException if
(myServiceLocator null)
myServiceLocator new corej2ee.project.ejb.Servic
eLocator() return
myServiceLocator
14 / Retrieves the EJBObject instance from
a previosly serialized handle
_at_param id serialized EJBObject handle
_at_throws ServiceLocatorException _at_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)
15 / Creates a serialized representation
for an EJBObject so it can be re-created
at a later time _at_param session EJBObject
to create a handle for _at_throws
ServiceLocatorException _at_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)
16 / Returns the home object for the
specified JNDI name _at_param name
JNDI name of the Home interface _at_param
clazz Specific Home class _at_throws
ServiceLocatorException _at_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)
17else Object objrefnull
System.out.println("Looking up home using
initial context")
synchronized(context) objref
context.lookup(name)
EJBHome home (EJBHome)PortableRemoteObject.nar
row(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 homeMapnew HashMap() // stores already
retrieved homes
18Client Usage
try System.out.println("Using
service locator") ServiceLocator
slServiceLocator.getInstance()
TellerHome home (TellerHome)
sl.getHome("TellerBean",corej2ee.project.ejb.Telle
rHome.class) Teller teller
home.create() Customer cnew
Customer("Dan")
teller.addCustomer(c)
teller.remove()
System.out.println("Test completed") catch(Remo
teException re)
19Service 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
20Business 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
21Proxy 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
22Implementation
public class TellerBusinessDelegate
publicTellerBusinessDelegate() throws
BusinessException try
TellerHome home (TellerHome)ServiceLocator.ge
tInstance().getHome(
"TellerBean", homeClazz) session
home.create() catch
(ServiceLocatorException ex)
throw new corej2ee.project.ejb.BusinessException(e
x) catch
(CreateException ex) throw new
corej2ee.project.ejb.BusinessException(ex)
catch (RemoteException ex)
throw new corej2ee.project.ejb.Busi
nessException(ex)
23 public TellerBusinessDelegate(String id) throws
BusinessException reconnect(id)
public String getID() throws
BusinessException try
return corej2ee.project.ejb.ServiceLocator.getI
d(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.getSer
vice(ID) catch
(ServiceLocatorException ex)
throw new corej2ee.project.ejb.BusinessException(e
x)
24 public void addCustomer(Customer c) throws
BusinessException try
session.addCustomer(c)
catch (java.rmi.RemoteException ex)
throw new corej2ee.project.ejb.BusinessExce
ption(ex) public
void transfer(int to,int from,double amount)
throws BusinessException try
session.transfer(to, from, amount)
catch (java.rmi.RemoteExcept
ion ex) throw new
corej2ee.project.ejb.BusinessException(ex)
25 public void removeCustomer(Customer c) throws
BusinessException try
session.removeCustomer(c)
catch (java.rmi.RemoteException ex)
throw new corej2ee.project.ejb.BusinessE
xception(ex) public
void close() if(session ! null)
try session.remove()
sessionnull catch(Exception
e)
26 protected void finalize() close()
/ _at_link _at_shapeType
PatternLink _at_pattern Business Delegate
Proxy Strategy _at_supplierRole Uses
/ / private BusinessException
_businessException / private Teller
session private Class homeClazz
TellerHome.class
27Client Program
package corej2ee.project.ejb public class
TellerClient public static void
main(String argv) try
TellerBusinessDelegate tellernew
TellerBusinessDelegate() Customer
cnew Customer("Dan")
teller.addCustomer(c) cnew
Customer("Cathy")
teller.addCustomer(c)
teller.close() catch
(BusinessException ex)
ex.printStackTrace()
28Business 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
29Other Sources
- http//developer.java.sun.com/developer/technicalA
rticles/J2EE/patterns