1.EJB中有三种bean
1.会话bean(session bean) 负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc直接操作数据库,但大多数情况下都是通过实体bean来完成对数据库的操作.
2.实体bean(entity bean) 它实际上属于java持久化规范(简称JPA)里的技术, JPA的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink等ORM框架各自为营的局面。
3.消息驱动bean(message-driven bean) 它是专门用于异步处理java消息的组件.具有处理大量并发消息的能力.
2.会话bean
无状态会话bean
平常,我们使用最多的是无状态bean,因为它的bean实例可供多个用户使用,所以它的性能比有状态bean高.正因为一个bean实例被多个用户使用.那么,前一个用户设置的值有可能被后一个用户所修改,所以它无法正确保存某个用户设置的值,因此是无状态的.
有状态会话bean
有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较大,正因为它的实例只被一个用户使用, 用户为它设置的值是不会被其他用户修改,所以可以正确保存用户设置的值,因此是有状态的.
3.
开发工具:Eclipse IDE for Java EE
开发时需要的EJB的jar包: 可以在jboss安装路径的client目录下找到,通常会把client目录下的所有jar文件添加到项目的类路径下.
4.开始创建第一个无状态会话bean
(1)创建一个项目工程HelloWorld
(2)把需要的Jar包加入工程
(3)创建接口:
代码如下:
package com.renwen.ejb3;
public interface HelloWorld {
public String sayHello(String name);
}
(4)创建实现类
代码如下:
package com.renwen.ejb3.impl;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import com.renwen.ejb3.HelloWorld;
//利用注解的方式声明
@Stateless//指明是无动态会话Bean
@Remote(HelloWorld.class)
public class HelloWorldBean implements HelloWorld {
public String sayHello(String name) {
return name+"说,你好,世界!";
}
}
(5)把工程打包:利用工具打成jar文件
(6)启动Jboss,把jar文件放在E:\jboss-4.2.3.GA\server\default\deploy下面
(7)dos窗口显示如下:
5:创建EJB的客户端
代码如下:
package com.renwen.test;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.renwen.ejb3.HelloWorld;
public class EJBClient {
public static void main(String[] args) {
Properties props = new Properties();
//用的服务器不同,下面的设置也是不同.这儿用的是JBoss服务器
//设置jdni的链接工厂
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
// //用来设置服务器的url
props.setProperty("java.naming.provider.url", "localhost:1099");
try {
InitialContext ctx = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("HelloWorldBean/remote");
System.out.println(helloworld.sayHello("小明"));
} catch (NamingException e) {
System.out.println(e.getMessage());
}
}
}
6.测试:
8.设置JNDI访问环境信息
如同数据库一样,根据访问命名服务器的不同,为上下文设置的驱动类和URL也是不同的,如下面是访问Sun应用服务器的上下文信息:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
props.setProperty("java.naming.provider.url", "localhost:3700");
InitialContext = new InitialContext(props);
HelloWorld helloworld = (HelloWorld) ctx.lookup("com.foshanshop.ejb3.HelloWorld");
如果客户端运行在应用服务器内,我们不需要为InitialContext设置应用服务器的上下文信息,也不建议设置。因为应用服务器启动时会把JNDI驱动类等上下文信息添加进系统属性,创建InitialContext对象时如果没有指定Properties参数,InitialContext内部会调用System.getProperty()方法从系统属性里获取必要的上下文信息。对本例子而言,你可以省略传入props参数,之所以给InitialContext设置参数,目的是引出相关知识点,便于教学。在实际应用中,如果给InitialContext设置了参数,反而会带来不可移植的问题。
注:创建InitialContext对象时如果没有指定Properties参数,InitialContext还会在classpath下寻找jndi.properties文件,并从该文件中加载应用服务器的上下文信息。这样避免了硬编码为InitialContext设置Properties参数。
jndi.properties的配置如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
[size=x-large]
9.JBoss默认生成jndi名称:[/size]
当EJB发布到Jboss 时,如果我们没有为它指定全局JNDI名称或修改过其默认EJB名称,Jboss就会按照默认的命名规则为EJB生成全局JNDI名称,默认的命名规则如下:
如果把EJB作为模块打包进后缀为*.ear的JAVA EE企业应用文件,默认的全局JNDI名称是
本地接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local
远程接口:EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote
EAR-FILE-BASE-NAME为ear文件的名称,EJB-CLASS-NAME为EJB的非限定类名。
例:把HelloWorld应用作为EJB模块打包进名为HelloWorld.ear的企业应用文件,它的远程接口的JNDI 名称是:HelloWorld/HelloWorldBean/remote
如果把EJB应用打包成后缀为*.jar的模块文件,默认的全局JNDI名称是
本地接口:EJB-CLASS-NAME/local
远程接口:EJB-CLASS-NAME/remote
例:把HelloWorld应用打包成HelloWorld.jar文件,它的远程接口的JNDI名称是:HelloWorldBean/remote
[size=x-large]
10.利用注释的方法可以改变 Session Bean的JNDI名称:[/size]
如果我们没有指定EJB的JNDI名称,当EJB发布到应用服务器时,应用服务器会按默认规则为EJB生成全局JNDI名称。当我们需要自定义JNDI名称时,可以这样做
如果EJB在Jboss中使用,可以使用Jboss提供的 @LocalBinding 和 @RemoteBinding 注释,@LocalBinding注释指定Session Bean的Local接口的JNDI名称,@RemoteBinding注释指定Session Bean的Remote接口的JNDI名称,如下:
@Stateless
@Remote ({Operation.class})
@RemoteBinding (jndiBinding="foshanshop/RemoteOperation")
@Local ({LocalOperation.class})
@LocalBinding (jndiBinding="foshanshop/LocalOperation")
public class OperationBean implements Operation, LocalOperation {
}