1. Trang chủ
  2. » Công Nghệ Thông Tin

Design ejb design patterns phần 9 pot

29 333 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 29
Dung lượng 101,53 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

public abstract class Command implements Serializable {public abstract void execute throws CommandException;... catch ClassCastException e {e.printStackTrace; }} public Command executeCo

Trang 1

public abstract class Command implements Serializable {

public abstract void execute() throws CommandException;

Trang 2

public void CommandServer() {}

public Command executeCommand(Command aCommand) throwsCommandException

{

try{aCommand.execute();

}catch (CommandException e){

Trang 3

public class EJBCommandTarget implements CommandTarget {

private CommandServerHome serverHome;

public EJBCommandTarget()

{

try

{

Context ctx = new InitialContext(System.getProperties());

Object obj = ctx.lookup(“CommandServer”);

Trang 4

catch (ClassCastException e) {

e.printStackTrace();

}}

public Command executeCommand(Command aCommand)

throws CommandException

{

try {CommandServer aCommandServer = serverHome.create();

aCommand = aCommandServer.executeCommand(aCommand);

return aCommand;

}catch (Exception e){

throw new CommandException(e);

}}

private static EJBCommandTarget ejbTarget = new EJBCommandTarget();

//execute command, overwriting memory reference of the passed //in command to that of the new one

public static Command execute(Command aCommand)

//under different transaction configurations)

return ejbTarget.executeCommand(aCommand);

}

}

Trang 5

Data Access Command Bean

The implementations of the abstract super classes BaseReadCommand and BaseUpdateCommand, as well as the InsertEmployeeCommand and QueryEmployeeByNameCommand classes are provided Note that the BaseReadCommand uses a RowSet to simplify its implementation RowSets are part of the JDBC 2.0 optional package, and joined core JDBC as of JDBC 3.0 The example here uses Sun’s free CachedRowSet implementation of the RowSet interface.

protected CachedRowSet rowSet = null;

private Connection con;

protected BaseReadCommand ( String jndiName, String statement )

Trang 6

public void execute() throws DataCommandException

{

try{rowSet = new CachedRowSet();

rowSet.populate(pstmt.executeQuery());

rowSet.beforeFirst();

this.release();

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}}

public boolean next() throws DataCommandException

{

try{return rowSet.next();

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}}

private void release() throws SQLException

{

if (pstmt != null) pstmt.close();

if (con != null) con.close();

}}

* The Super class for any data command beans that Create, Update or

* Delete This class is reusable across projects, all proj specificdata

* (Datasource JDNI and SQl String) are left to the subclasses

*/

abstract class BaseUpdateCommand {

Trang 7

protected PreparedStatement pstmt;

private Connection con;

protected BaseUpdateCommand ( String jndiName, String statement )

Trang 8

* is the usecase specific Command bean that

* an application developer would write

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}}

public void setId(int id) throws DataCommandException

{

try{pstmt.setInt(1, id);

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}}

public void setName(String aName) throws DataCommandException{

try{pstmt.setString(2, aName);

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}

}

Trang 9

static final String statement =

“select EMPLOYEEID, NAME, EMAIL from Employees where NAME = ?”;

static final String dataSourceJNDI = “bookPool”;

protected QueryEmployeeByNameCommand() throws DataCommandException

Trang 10

throw new DataCommandException(e.getMessage());

}}

public void setName(String aName) throws DataCommandException

{

try{pstmt.setString(1, aName);

} catch (SQLException e){

throw new DataCommandException(e.getMessage());

}}

}

Dual Persistent Entity Bean

Included is the code example of the bank account entity bean inheritance tionship and deployment descriptors These classes can be compiled and then deployed in CMP or BMP by swapping the provided deployment descriptors.

rela-Account Deployment Descriptor for

Trang 12

public interface Account extends EJBObject {

public double balance() throws RemoteException;

public double deposit(double amount) throws RemoteException;public double withdraw(double amount) throws

public interface AccountHome extends EJBHome {

public Account create(String accountId, double initialBalance)throws CreateException, RemoteException;

public Account findByPrimaryKey(String primaryKey)

throws FinderException, RemoteException;

public Collection findBigAccounts(double balanceGreaterThan)throws FinderException, RemoteException;

Trang 13

Account CMP Bean Superclass

abstract public String getAccountId();

abstract public double getBalance();

abstract public void setAccountId(String val);

abstract public void setBalance(double val);

Trang 14

public String ejbCreate(String accountId, double initialBalance)throws CreateException

public void ejbActivate() {}

public void ejbLoad() {}

public void ejbPassivate() {}

public void ejbPostCreate(String accountId,double initialBalance){}public void ejbRemove() throws RemoveException {}

public void ejbStore() {}

Trang 15

private String accountId;

private double balance;

public String getAccountId()

Trang 16

if (ps != null) ps.close();

if (con != null) con.close();

} catch (Exception e){

throw new EJBException(e);

}}}

public Collection ejbFindBigAccounts(double balanceGreaterThan){

Connection con = null;

PreparedStatement ps = null;

try{con = getConnection();

ps = con.prepareStatement(“select id from Accounts where

pk = rs.getString(1);

v.addElement(pk);

}return v;

} catch (SQLException e){

throw new EJBException(e);

} finally{

try{

if (ps != null) ps.close();

if (con != null) con.close();

} catch (Exception e){

throw new EJBException(e);

}}}

Trang 17

throw new ObjectNotFoundException();

} catch (SQLException sqe)

Trang 18

elsethrow new NoSuchEntityException();

} catch (SQLException sqe){

throw new EJBException(sqe);

} finally{

try{

if (ps != null) ps.close();

if (con != null) con.close();

} catch (Exception e){

System.out.println(“Error closing JDBC resourcest: “ +e);

throw new EJBException(e);

}}}

public void ejbPostCreate(String accountId, double initialBalance){

accountId = (String) ctx.getPrimaryKey();

ps = con.prepareStatement(“delete from Accounts where id =

?”);

ps.setString(1, accountId);

Trang 19

throw new NoSuchEntityException();

} catch (SQLException sqe)

Trang 20

return ds.getConnection();

} catch (NamingException e){

throw new EJBException(e);

}}

EJB Home Factory

Here we present an example of an EJB Home Factory

Simple EJB Home Factory

* EJB Home Factory, maintains a simple hashmap cache of EJBHomes

* For a production implementations, exceptions such as NamingException

* can be wrapped with a factory exception to futher simplify

* the client

*/

public class EJBHomeFactory

{

private Map ejbHomes;

private static EJBHomeFactory aFactorySingleton;

Trang 21

* Returns the singleton instance of the EJBHomeFactory

* The sychronized keyword is intentionally left out the

* as I don’t think the potential to intialize the singleton

* twice at startup time (which is not a destructive event)

* is worth creating a sychronization bottleneck on this

* VERY frequently used class, for the lifetime of the

* client application

*

* Alternatively, you can sychronize this method, OR you can

* simply Intialize the hashMap and factory using static

* Lookup and cache an EJBHome object using a home class

* Assumes that the JNDI name of the EJB Home being looked for

* is the same as the fully qualified class name of the

* same EJB Home

* If EJB-REF tags are being used externally, then the classname

* of the EJB Home can be mapped to the actual JNDI name of the

* deployed bean transaprently at deployment time

* If EJB-REF tags are not used, then the EJB’s must be deployed

Trang 22

anEJBHome = (EJBHome) PortableRemoteObject.narrow

(ctx.lookup (homeClass.getName()),homeClass);

this.ejbHomes.put(homeClass, anEJBHome);

}}catch (ClassCastException e){

throw new HomeFactoryException(e);

}catch (NamingException e){

throw new HomeFactoryException(e);

}

return anEJBHome;

}

/**

* Lookup and cache an EJBHome object

* This ‘alternate’ implementation delegates JNDI name knowledge

* to the client It is included here for example only

System.out.println(“finding HOME for first time”);anEJBHome = (EJBHome) PortableRemoteObject.narrow

Trang 23

this.ejbHomes.put(homeClass, anEJBHome);

}}

The changed/extra code (over the stateless delegate example in Chapter 8)

is highlighted in bold The only major change in the SFSB version of the

Busi-ness Delegate is the use of a getEJB() method before every invocation of a ness method on an EJB This is done to ensure that the EJBObject still exists (was not lost in serialization), in order to recreate it from the handle in case of

busi-serialization Also, clients must remember to call remove on the delegate when

they are done with it, so that the SFSB can be removed.

public class ForumServicesDelegate implements Serializable

{

private transient TestSession sb;

private Handle remoteHandle;

public ForumServicesDelegate() throws DelegateException

Trang 24

throw new DelegateException();

}}

//business method

public long addForum(long categoryPK, String forumTitle,

String summary) throws NoSuchCategoryException,DelegateException {

try{

return getEJB().sb.addForum

(categoryPK, forumTitle, summary);

} catch(CreateException e){

throw new DelegateException();

//log errors, etc} catch(RemoteException e){

throw new DelegateException();

//log errors, etc}

//if so, recreate session bean reference

sb = (ForumServices) PortableRemoteObject.narrow (remoteHandle.getEJBObject(),ForumServices.class); }

} catch (ClassCastException e) {

throw new DelegateException();

Trang 25

//once the client is done with the

//stateful delegate, allow client to call

//remove, so we can tell the EJB server to

Included is a complete implementation of the Sequence Block pattern, based

on a submission by Jonathan Weedon from Borland Corporation The Sequence entity bean exposes only local interfaces (it is only called by the Sequence Session Bean) The Sequence Session Bean exposes both local and remote interfaces (should be called by local interfaces in production; remote is provided for testing purposes) Ejb-jar.xml descriptors are also included

Sequence Entity Bean Local Interface

Trang 26

Sequence Entity Bean Local Home

abstract public int getIndex();

abstract public String getName();

abstract public void setIndex(int newIndex);

abstract public void setName(java.lang.String newName);

public void ejbActivate() {}

public void ejbLoad() {}

public void ejbPassivate() {}

public void ejbPostCreate(String name) {}

public void ejbRemove() {}

public void ejbStore() {}

public void setEntityContext(EntityContext unused) {}

public void unsetEntityContext() {}

Trang 27

Sequence Session Remote Interface

package examples.sequencegenerator;

import java.rmi.*;

public interface SequenceSession extends javax.ejb.EJBObject {

public int getNextNumberInSequence(String name) throws

public interface SequenceSessionHome extends javax.ejb.EJBHome {

SequenceSession create() throws CreateException, RemoteException;

}

Sequence Session Local Interface

package examples.sequencegenerator;

public interface SequenceSessionLocal extends javax.ejb.EJBLocalObject {

public int getNextNumberInSequence(String name);

Trang 28

private class Entry {

private int _retryCount;

private SequenceLocalHome _sequenceHome;

public int getNextNumberInSequence(String name)

// add an entry to the sequence tableentry = new Entry();

try{entry.sequence = _sequenceHome.findByPrimaryKey(name);}

catch (javax.ejb.FinderException e){

// if we couldn’t find it, then create it

entry.sequence = _sequenceHome.create(name);

}_entries.put(name, entry);

}

if (entry.last % _blockSize == 0){

for (int retry = 0; true; retry++){

try{entry.last = entry.sequence.getNextKeyAfterIncrementingBy(_blockSize);break;

}catch (javax.ejb.TransactionRolledbackLocalException e){

if (retry < _retryCount){

// we hit a concurrency exception, so //try again

continue;

Trang 29

else{// we tried too many times, so fail

throw new javax.ejb.EJBException(e);

}}}}

public void ejbActivate() {}

public void ejbCreate() {}

public void ejbPassivate() {}

public void ejbRemove() {}

}

Sequence Session and Entity

EJB-JAR.xml

<?xml version=”1.0”?>

<!DOCTYPE ejb-jar PUBLIC ‘-//Sun Microsystems,

Inc.//DTD Enterprise JavaBeans 2.0//EN’

‘http://java.sun.com/dtd/ejb-jar_2_0.dtd’>

Ngày đăng: 09/08/2014, 16:20

TỪ KHÓA LIÊN QUAN