EJB中的三种bean
1.会话bean(session bean)
负责与客户端交互,是编写业务逻辑的地方,在会话bean中可以通过jdbc 直接操作数据库,
但大多数情况下都是通过实体bean来完成对数据库得操作。
会话bean 又可以分为2种
.无状态会话bean
平常,我们使用最多的是无状态bean,因为它的bean 实例可供多个用户使用,所以它的性能比
有状态bean高,正因为一个bean实例被多个用户使用,那么,前一个用户设置的值有可能被后
一个用户所修改,所以它无法 正确保存某个用户设置的值,因此是无状态的
.有状态会话bean
有状态bean平常使用的并不多,因为它的一个bean实例只供一个用户使用,所以性能开销比较
大,正因为它得实例只能被一个用户使用,那么,用户设置的值是不会被其他用户所修改,所以
可以正确保存用户设置的值,因此是有状态的。
2.实体bean(entity bean)
它实际上属于java 持久化规范(简称jpa)里的技术,jpa的出现主要是为了简化现有得持久化开发
工作和整合ORM技术, 结束现在hibernate TOPlink等ORM框架各自为盈的局面。
3.消息驱动bean(message-driven bean)
它是专门用于异步处理java消息的组件,具有处理大量并发消息的能力。
开发EJB依赖的jar文件
可以在jboss安装路径的client目录下找到,通常会把client目录下的所有jar文件添加到项目的路径下
接口可以是本地接口,也可以是远程接口 EJB属于业务层
EJB3.0 开发第一个无状态会话bean
接口
package com.launch.out;
public interface HelloWord {
public String say(String name);
}
实现
package com.launch.impl;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import com.launch.out.HelloWord;
@Stateless
@Remote(HelloWord.class)
public class HelloWordBean implements HelloWord {
public String say(String name) {
return name+"how are you .";
}
}
完成后打成jar包
开发EJB的客户端
客户端要调用EJB,它是需要通过jndi去寻找EJB的存根代理对象。
如果客户端运行在服务器内,我们不需要去为InitialContext设置应用上下文信息,也不建议设置。
因为应用服务器会把jndi驱动类等上下文信息添加进系统属性,创建InitialContext对象时如果没有指定
Properties参数,InitialContext内部会调用System.getProperty()方法从系统属性里读取必要的上下文信息,
对本例子而言,你可以省略传入Properties 参数,之所以给InitialContext设置参数,目的是引出相关知识
在实际应用中,如果给InitialContext设置了参数,反而会带来不可移植的问题
注:创建InitialContext对象时如果没有指定Properties参数,InitialContext还会在CLASSPATH下寻找
jndi.properties文件 ,并从该文件中加载应用服务器的上下文信息。这样避免了硬编码为InitialContext
设置Properties参数。
jndi.perperties 的设置如下
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
客户端调用
import javax.naming.*;
import java.util.Properties;
public class test {
public static void main(String args[]){
设置的JNDI的上下文信息
Properties props = new Properties();
//JNDI规范所规定 后面的是JBOSS的JNDI连接工厂
//org.jnp.interfaces.NamingContextFactory这个类是在安装jboss下client目录下jnp-clent.jar
// jndi通过这个连接工厂就可以和JBOSS通讯了
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);
//根据EJB jndi名称 查询HelloWordBean/remote存根代理对象
HelloWord helloworld = (HelloWord) ctx.lookup("HelloWordBean/remote");
System.out.println(helloworld.say("佛山人"));
} catch (NamingException e) {
System.out.println (e.getMessage());
}
}
}
这里编写的客户端程序完全可以部署在另外一台计算机上,只需要修改其中连接的服务器ip
地址和启动jboss时绑定相应ip地址即可,这正是ejb的远程调用特性。
返回的helloword实例对象并不是我们在服务器端编写得HelloworldBean.
而是一个也实现了Helloworld接口的代理对象。这个代理对象最终远程调用我们自己编写的HelloworldBean,
可以加如
System.out.println(helloworld.getClass().getName());
jboss 默认生成的jndi名称
当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
看看是否发布成功
http://local:8080/jmx-console/
找到jboss
点击 service=JNDIView进去后
List of MBean operations
java.lang.String.list()
点击 invoke 按钮 进去
Global JNDI Namespace
如果看到我们发布的jndi名称,就说明是发布成功了。