EJB实例化池来管理服务器端组件的实例。实例化池只能应用于stateless session bean 和message-driven bean。
Stateless Session Bean的生命周期比较简单,只有两个状态 does not exist 和method-ready pool
Statefule Session Bean必须实现Serializable接口,方便EJB容器在不使用时,把这些对象序列化保存到硬盘。对于stateful session bean,用户每一次调用lookup()都会创建一个新的bean实例,如果希望一直使用某个bean实例,则必须在客户端缓存存根。
对于statefule session bean,从效率的角度出发,在ejb服务器需要节省资源时,就从内存中收回bean实例,将其所保持的会话状态序列化到硬盘中,并且释放其所占有的内存。若此时客户端对EJB再次发起请求,EJB容器会重新实例化一个bean实例,并从硬盘中将之前的状态恢复。(钝化passivation)
Statefule Session Bean的生命周期有3种状态:dose not exist、method-ready 和passivation
接口:
package com.manfred.ejb;
import java.io.Serializable;
import java.util.List;
public interface Cart extends Serializable {
public void AddBuyItem(String productName);
public List<String> getBuyItems();
}
package com.manfred.ejb.impl;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateful;
import com.manfred.ejb.Cart;
@SuppressWarnings("serial")
@Stateful
@Remote({ Cart.class })
public class CartBean implements Cart {
private List<String> buyItems = new ArrayList<String>();
public void AddBuyItem(String productName) {
buyItems.add(productName);
}
public List<String> getBuyItems() {
return buyItems;
}
}
web项目的index.jsp
<%@page import="com.manfred.ejb.Cart"%>
<%@ page language="java" import="java.util.*,javax.naming.*,com.manfred.ejb.impl.*" pageEncoding="GB18030"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page. <br>
============================================<br>
客户端远程访问<br>
<%
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context context = null;
try {
context = new InitialContext(jndiProperties);
final String appName = "";
final String moduleName = "EJB_04_stateful";
final String distinctName = "";
final String beanName = "CartBean";
final String viewClassName = Cart.class.getName();
String jndi = "ejb:" + appName + "/" + moduleName + "/" + distinctName + "/"
+ beanName + "!" + viewClassName + "?stateful";
Cart cart = (Cart) session.getAttribute("cart");
if(cart == null){
cart = (Cart) context.lookup(jndi);
session.setAttribute("cart", cart);
}
cart.AddBuyItem("上下五千年");
List<String> buyItems = cart.getBuyItems();
out.println("购物车的购物清单:<br>");
for(String s : buyItems){
out.println(" " + s + "<br>");
}
} catch (Exception e) {
e.printStackTrace();
}
%>
</body>
</html>