一 Stateless Session Beans( 无状态 bean) 的学习 第一步 : 要定义一个会话 Bean, 首先需要定义一个包含他所有业务方法的接口 这个接口不需要任何注释, 就像普通的 java 接口那样定义 调用 EJB 的客户端通过使用这个接口引用从 EJB 容器得到的会话 Bean 对象 stub 接口的定义如下: HelloWorld.java package com.foshanshop.ejb3; public interface HelloWorld { public String SayHello(String name); 第二步 : 实现上面的接口并加入两个注释 @Stateless, @Remote, 第一个注释定义这是一个无状态会话 Bean, 第二个注释指明这个无状态 Bean 的 remote 接口 在使用这两个注释时需要使用一些 EJB 的类包, 这些类包都可以在 jboss 安装目录的 client, /server/all/deploy/jboss-aop-jdk50.deployer,/server/all/deploy/ejb3.deployer,/lib/endorsed 等文件夹下找到, 或者在源代码的 Lib 文件夹下获得 ( 下载地址 :http://www.foshanshop.net/) 经过上面的步骤一个只存在 Remote 接口的无状态会话 Bean 就开发完成 无状态会话 Bean 是一个简单的 POJO( 纯粹的面向对象思想的 java 对象 ),EJB3.0 容器自动地实例化及管理这个 Bean 下面是 HelloWorld 会话 Bean 的实现代码 : HelloWorldBean.java 实现类的命名规则是: 接口 +Bean, 如 : HelloWorldBean package com.foshanshop.ejb3.impl; import com.foshanshop.ejb3.helloworld; import javax.ejb.remote; import javax.ejb.stateless; @Stateless @Remote ({HelloWorld.class) public class HelloWorldBean implements HelloWorld { public String SayHello(String name) { return name +" 说 : 你好! 世界, 这是我的第一个 EJB3 哦."; 发布成功, 在 jboss 的管理平台查看她们的 JNDI 名, 输入下面 URL http://localhost:8080/jmx-console/ 点击 service=jndiview, 查看 EJB 的 JNDI 名称 ( 如下图 ) 在出现的页面中, 找到 List of MBean operations: 栏 点击 Invoke 按钮, 出现如下界面可以看见 HelloWorld 会话 Bean 的 JNDI 名,JNDI 名的组成规则是 上层名称 / 下层名称, 每层之间以 / 分隔 HelloWorld 会话 Bean 的 JNDI 名是 :HelloWorldBean/remote HelloWorld 会话 Bean 发布成功当一个无状态会话 Bean 发布到 EJB 容器时, 容器就会为她创建一个对象 stub, 并把她注册进容器的 JNDI 目录, 客户端代码使用她的 JNDI 名从容器获得他的 stub 通过这个 stub, 客户端可
以调用她的业务方法 例子代码如下 : Test.jsp <%@ page contenttype="text/html; charset=gbk"%> <%@ page import="com.foshanshop.ejb3.helloworld, javax.naming.*, java.util.properties"%> <% Properties props = new Properties(); props.setproperty("java.naming.factory.initial", "org.jnp.interfaces.namingcontextfactory"); props.setproperty("java.naming.provider.url", "localhost:1099"); props.setproperty("java.naming.factory.url.pkgs", "org.jboss.naming"); InitialContext ctx; try { ctx = new InitialContext(props); HelloWorld helloworld = (HelloWorld) ctx.lookup("helloworldbean/remote"); out.println(helloworld.sayhello(" 东方通 ")); catch (NamingException e) { out.println(e.getmessage()); %> 说明一下 JBOSS 环境 EJB JNDI 名称默认的命名规则, 命名规则如下 : 1> 如果 EJB 应用打包成后缀为 *.ear 的发布文件, 默认的 JNDI 名称是访问本地接口 :EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local 访问远程接口 :EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote 例 : 如果 HelloWorld 应用打包成 HelloWorld.ear 文件, 访问她远程接口的 JNDI 名是 : HelloWorld/HelloWorldBean/remote 2> 如果 EJB 应用打包成后缀为 *.jar 的发布文件, 默认的 JNDI 名称是访问本地接口 :EJB-CLASS-NAME/local 访问远程接口 :EJB-CLASS-NAME/remote 例 : HelloWorld 应用打包成 HelloWorld.jar 文件, 访问她远程接口的 JNDI 名称是 : HelloWorldBean/remote 另外有一点要注意 :EJB-CLASS-NAME 是不带包名的, 如 com.foshanshop.ejb3.impl.helloworldbean 只需取 HelloWorldBean 最后 :war 文件的文件名为 EJBTest.war,http://localhost:8080/EJBTest/Test.jsp 访问客户端 改进部分 :EJB JNDI 名称 JBOSS 和 TW5.0 不同 JBOSS 环境 EJB JNDI 名称默认的命名规则, 命名规则如下 : 1> 如果 EJB 应用打包成后缀为 *.ear 的发布文件, 默认的 JNDI 名称是访问本地接口 :EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local 访问远程接口 :EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote 例 : 如果 HelloWorld 应用打包成 HelloWorld.ear 文件, 访问她远程接口的 JNDI 名是 : HelloWorld/HelloWorldBean/remote
2> 如果 EJB 应用打包成后缀为 *.jar 的发布文件, 默认的 JNDI 名称是访问本地接口 :EJB-CLASS-NAME/local 访问远程接口 :EJB-CLASS-NAME/remote 例 : HelloWorld 应用打包成 HelloWorld.jar 文件, 访问她远程接口的 JNDI 名称是 : HelloWorldBean/remote TW5.0 EJB JNDI 名称与 JBOSS 不同 : 包名.remote 的类名 lifecycle1=(lifecycleremote)ctx.lookup("lifecycle1.lifecycleremote" ); 在 TW5.0 中,SESSION BEAN 例子 lifecyclebean1.java 如下 : package lifecycle1; import javax.ejb.*; import javax.annotation.postconstruct; import javax.annotation.predestroy; /** * Session Bean implementation class lifecyclebean1 */ @Stateful @Remote(lifecycleRemote.class) public class lifecyclebean1 implements lifecycleremote { @Init public void initialize(){ System.out.println(" 使用 @Init 注解的方法被调用 "); @PostConstruct public void Construct(){ System.out.println(" 使用 @PostConstruct 注解的方法被调用 "); @PreDestroy public void exit(){ System.out.println(" 使用 @PreDestroy 注解的方法被调用 "); @Remove public void stopbean(){ System.out.println(" 使用 @Remove 注解的方法被调用 "); public String operate(){ System.out.println(" 使用业务方法被调用 "); return " 调用业务方法 ";
在 TW5.0 中,lifecycleRemote.java 如下 package lifecycle1; import javax.ejb.remote; @Remote public interface lifecycleremote { public String operate(); public void stopbean(); JSP 调用 SESSION BEAN 如下 : <%@ page language="java" contenttype="text/html; charset=gbk"%> <%@ page import="lifecycle1.*, javax.naming.*"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"> <title>insert title here</title> </head> <body> <% try{ InitialContext ctx=new InitialContext(); lifecycleremote lifecycle1=(lifecycleremote)session.getattribute("lifecycle1"); if(lifecycle1==null){ // 创建购物车 lifecycle1=(lifecycleremote)ctx.lookup("lifecycle1.lifecycleremote" ); // 访问远程接口与 JBOSS 不同 : 包名.remote 的类名 session.setattribute("lifecycle1",lifecycle1); // 缓存 out.println(lifecycle1.operate()); lifecycle1.stopbean(); catch(exception e){ e.printstacktrace(); %> </body> </html>
具体例子见附件 lifecycle1.ear.rar