⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib0095.html

📁 j2ee架构师手册
💻 HTML
字号:
<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Session Beans</title>
<link rel="STYLESHEET" type="text/css" href="images/xpolecat.css">
<link rel="STYLESHEET" type="text/css" href="images/ie.content.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle"  alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0094.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0096.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
<br>
<div class="chapter">
<a name="ch14"></a>
<div class="section">
<h2 class="first-section-title"><a name="455"></a><a name="ch14lev1sec1"></a>Session Beans</h2><p class="first-para">Session beans are a good choice for publishing functionality to multiple applications. In many environments, several applications run on separate <a name="456"></a><a name="IDX-187"></a>servers. By separating the application servers from where the servlet engine and the EJB container run, you can provide additional scalability and availability.</p>
<p class="para">Session beans are also a good choice if you need tight coupling between two or more applications. Large organizations usually put applications in separate containers. If tight coupling between two applications exists (e.g., between an order entry and order fulfillment application), beans allow these applications to work in tandem yet be sized separately for the resources they need.</p>
<p class="para">Because they are flexible and accessible by many different types of applications, session beans are also useful when the business object functionality is supporting multiple presentation tiers. I've worked on several applications in which the Web tier and administration tools were run as stand-alone applications. Enterprise beans allowed both applications to use the same services.</p>
<p class="para">In a layered architecture where session beans publish but do not implement business logic, bean method signatures tend to be identical to method signatures in a business object. For example, consider <a class="internaljump" href="#ch14list01">listing 14.1</a>, which is a session bean deployment for the <span class="fixed">PurchaseOrder</span> class developed in <a href="LiB0081.html#373" target="_parent" class="chapterjump">chapter 12</a>.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 14.1: </span>Sample Session Bean Deployment</span><a name="457"></a><a name="ch14list01"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
   1:package book.sample.deploy.po;
   2:
   3:import book.sample.bo.PurchaseOrder;
   4:// some code omitted.
   5:
   6:public class PurchaseOrderBean
   7:    extends DefaultSessionBean
   8:{
   9:  public void recordPurchaseOrder(PurchaseOrderVO poVO)
  10:     throws     InsufficientCreditException,
  11:                 InternalApplicationException
  12:  {
  13:    try
  14:    {
  15:      J2EETransactionContext context =
  16:         new J2EETransactionContext(
  17:             this._sessionContext);
  18:      PurchaseOrder po = new PurchaseOrder( context,
  19:                                             poVO);
  20:      po.record();<a name="458"></a><a name="IDX-188"></a>
  21:    }
  22:    catch (InsufficientCreditException ice)
  23:    {
  24:        throw ice;
  25:    }
  26:    catch (InternalApplicationException iae)
  27:    {
  28:      LogManager.getLogger().logError(iae.getMessage(),
  29:                                        iae);
  30:      throw iae;
  31:    }
  32:    catch (Throwable t)
  33:    {
  34:      StringBuffer message = new StringBuffer();
  35:      message.append("Error recording PO ==&gt; ");
  36:      if (poVO != null)
  37:      {
  38:          message.append(poVO.describe());
  39:      }
  40:      else message.append("null");
  41:
  42:      LogManager.getLogger().logError(
  43:          message.toString(), t);
  44:      throw new InternalApplicationException
  45:            ( message.toString(), t);
  46:    }
  47:  }
  48:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="para">
<i class="emphasis">Source:</i> /src/book/sample/po/PurchaseOrderBean.java</p>
<p class="para">
<b class="bold">The signature for an application method on the session bean corresponds</b> <b class="bold">to that of an object in the business logic layer.</b> Remember that the bean isn't adding any business logic, it's just making a class in the busiess logic layer callable as an enterprise bean from remote machines.</p>
<p class="para">Notice that <a class="internaljump" href="#ch14list01">listing 14.1</a> extends <span class="fixed">DefaultSessionBean</span> instead of implementing the <span class="fixed">SessionBean</span> interface directly. <span class="fixed">DefaultSessionBean</span> is a convenience class in CemetJ that provides a default implementation for a session bean. I typically extend that to cut down the number of lines of code. If you do need to put logic in <span class="fixed">ejbActivate()</span>, <span class="fixed">ejbPassivate()</span>, or one of the other <span class="fixed">SessionBean</span> methods, you can easily provide an override.</p>
<p class="para">
<b class="bold">Deployment wrappers should perform error logging.</b> The deployment wrappers are the last opportunity your application has to log before control is returned to a caller that might be on a remote machine. If your application will be the only code calling the session bean, it's possible to move logging <a name="459"></a><a name="IDX-189"></a>to the servlet or the Struts action class that calls the bean. <a href="LiB0111.html#536" target="_parent" class="chapterjump">Chapter 17</a> provides more detail on logging issues.</p>
<p class="para">Whether it's better to use Log4J or the API logging provided in version 1.4 of the JDK is the topic of current debate. I typically decouple my loggers with interfaces. Similarly, CementJ implements a logging interface that can use either of these two logging packages and can easily be implemented for any other logging package you might want to use.</p>
<p class="para">
<b class="bold">All exceptions thrown should implement </b><b class="bold"><span class="fixed">java.io.Serializable</span></b>. Otherwise, the client will likely receive a marshaling exception instead of the meaningful exception you tried to throw. In <a class="internaljump" href="#ch14list01">listing 14.1</a>, both <span class="fixed">InsufficientCreditException</span> and <span class="fixed">InternalApplicationException</span> are serializable. Incidentally, if exceptions extend either <span class="fixed">Application-Exception</span> or <span class="fixed">ApplicationRuntimeException</span> from CementJ, they automatically implement <span class="fixed">Serializable</span> as well as track the root exception with stack trace.</p>
<p class="para">
<b class="bold">Using stateless session beans improve performance.</b> A stateful session bean remembers information from a user's previous calls, whereas a stateless session bean does not. You should use stateful session beans if you're supporting multiple presentation tiers (e.g., HTML/JSPs, applets, and a heavy client-side application deployment). If your application requires you to maintain state, you won't want to replicate the state management logic in each presentation tier.</p>
<p class="para">
<b class="bold">Stateless session beans should avoid instance-level variables.</b> There's really no need for them in a stateless bean. A possible exception is storing the <span class="fixed">SessionContext</span> provided by the container so that you have easy access to the <span class="fixed">UserTransaction</span> for transaction management.</p>
<p class="para">In an effort to be nice to my customers (callers), I provide a client implementation of the bean so they don't have to write what is in essence the same code. <a class="internaljump" href="#ch14list02">Listing 14.2</a> illustrates this concept.</p>
<div class="example">
<span class="example-title"><span class="example-titlelabel">Listing 14.2: </span>Sample Session Bean Client</span><a name="460"></a><a name="ch14list02"></a>
<div class="formalbody">
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="Start example" border="0"></b></font></td>
</tr>
</table>
<pre class="literallayout">
   1:package book.sample.client;
   2:
   3:// some code omitted
   4:
   5:public class PurchaseOrderClient
   6:{
   7:  public PurchaseOrderClient() throws NamingException,<a name="461"></a><a name="IDX-190"></a>
   8:                     CreateException,
   9:                     RemoteException
  10:  {
  11:   _controller = this.getController();
  12:  }
  13:
  14:  public void recordPurchaseOrder(PurchaseOrderVO po)
  15:     throws InsufficientCreditException,
  16:        InternalApplicationException,
  17:        RemoteException
  18:  {
  19:   _controller.recordPurchaseOrder(po);
  20:  }
  21:
  22:  public PurchaseOrderVO[] getPOsForCustomer (
  23:          String customerId)
  24:    throws InternalApplicationException,
  25:           RemoteException
  26:  {
  27:      return _controller.getPOsForCustomer(customerId);
  28:  }
  29:
  30:  private PurchaseOrderController getController()
  31:      throws     NamingException,
  32:                  CreateException,
  33:                  RemoteException
  34:  {
  35:    PurchaseOrderController controller = null;
  36:    Context ctx = new InitialContext();
  37:
  38:    Object home =
  39:        ctx.lookup("PurchaseOrderControllerHome");
  40:    PurchaseOrderControllerHome controllerHome =
  41:        (PurchaseOrderControllerHome)
  42:              PortableRemoteObject.narrow(home,
  43:                  PurchaseOrderControllerHome.class);
  44:    controller = (PurchaseOrderController)
  45:        PortableRemoteObject.narrow (
  46:            controllerHome.create(),
  47:            PurchaseOrderController.class);
  48:
  49:    return controller;
  50:  }
  51:
  52:  private PurchaseOrderController _controller = null;
  53:}
</pre>
<table class="BlueLine" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td bgcolor="000080" class="bluecell"><font size="2" face="Arial" color="010100"><b><img src="_.gif" width="1" height="2" alt="End example" border="0"></b></font></td>
</tr>
</table>
<table class="BlankSpace" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td height="16"></td>
</tr>
</table>
</div>
</div>
<p class="last-para">
<i class="emphasis">Source:</i> /src/book/sample/client/PurchaseOrderClient.java</p>
</div>
</div><br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/teamlib.gif" width="62" height="15" border="0" align="absmiddle"  alt="Team LiB"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href="LiB0094.html"><img src="images/previous.gif" width="62" height="15" border="0" align="absmiddle" alt="Previous Section"></a>
<a href="LiB0096.html"><img src="images/next.gif" width="41" height="15" border="0" align="absmiddle" alt="Next Section"></a>
</div></td></tr></table>
</body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -