EJB分类:1.
会话bean(session bean)负责与客户端交互,是编写业务逻辑的地方,在session bean中操作数据库有两种方式:
•通过jdbc直接操作数据库(不常用)
•通过entity bean完成对数据库的操作
session bean分为有状态(stateful)会话bean和无状态(stateless)会话bean。
stateless session bean:
平时使用的比较多,它的bean实例可供多个用户使用,所以性能比stateful session bean性能高。前一个用户设置的值有可能被后一个用户所修改,所以无法保存某个用户设置的值,因此是无状态的。
stateful session bean:
使用的比较少,一个bean实例只供一个用户使用,性能开销大。用户设置的值不会被其它用户修改,可以正确保存用户设置的值。典型应用是购物车。
2.
实体bean(会话bean)它实际上数据Java持久化规范(JPA:Java Persistence API)里的技术,JPA的出现主要是为了简化现有的持久化开发工作和整合ORM(Object-Relational Mapping)技术,结束现在Hibernate/Toplink等ORM框架各自为营的局面。
3.
消息驱动bean(message-driven bean)它是专门用于异步处理Java消息的组件,具有处理大量并发消息的能力。
开发EJB依赖的jar文件在JBOSS_HOME/client下,通常把该目录下的所有jar文件引入到工程中。
如何开发一个stateless bean:接口(远程接口或本地接口)
实现类
实例:接口
1 package cn.jvpy.ejb3;
2
3 public interface HelloWorld {
4 public String sayHello(String name);
5 }
实现
HelloWorldBean.java
1 package cn.jvpy.ejb3.impl;
2
3 import javax.ejb.Remote;
4 import javax.ejb.Stateless;
5
6 import cn.jvpy.ejb3.HelloWorld;
7
8 @Stateless
9 @Remote(HelloWorld.class)
10 public class HelloWorldBean implements HelloWorld {
11
12 public String sayHello(String name) {
13 return name + " said: Hello EJB3!";
14 }
15
16 } EJB的客户端
EJBClient.java
1 package cn.jvpy.test;
2
3 import java.util.Properties;
4
5 import javax.naming.InitialContext;
6 import javax.naming.NamingException;
7
8 import cn.jvpy.ejb3.HelloWorld;
9
10 public class EJBClient {
11
12 public static void main(String[] args) {
13 Properties props = new Properties();
14 // 根据不同的服务器有不同的设置,下面是JBoss的设置
15 props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
16 props.setProperty("java.naming.provider.url", "localhost:1099");
17 try {
18 InitialContext ctx = new InitialContext(props);
19 HelloWorld helloWorld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");
20 System.out.println(helloWorld.sayHello("Xiao Ming"));
21 } catch (NamingException e) {
22 System.out.println(e.getMessage());
23 }
24 }
25
26 } 上面EJBClient中对jndi的设置是硬编码设置的,也可以通过jndi.properties文件设置,并将该文件放到项目的类路径下面(在eclipse中可以放到源文件下,编译的时候会自动编译进类路径)。
如下:1 java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
2 java.naming.provider.url=localhost:1099
这时在EJBClient中可以去掉13~16行,只需要如下一行
,InitialContext 会自动在类路径下寻找jndi的配置文件
InitialContext ctx = new InitialContext();
文件分布如下
上面的例子是具有remote接口的session bean。如果不加标注(@Remote or @Local),默认为本地接口。
当把上面的remote相应的改成local的时候,程序无法运行,抛出EJBException,这是因为客户端并没有发布到ejb所在的jboss中,即客户端与ejb在不同的JVM内。
这时可以建立一个web工程,将要测试的本地接口工程类加入到web工程的Java build path中,将该工程打包成war文件部署到jboss的deploy目录下,然后在jsp页面中对local接口进行测试。
jsp页面如下:工程结构:
运行结果: