EJB:快速入门
- 1、EJB概念
- 2、EJB体系结构
- 3、SessionBean
- 3.1 SessionBean 服务端组件
- 3.2 Remote 与 Local 模式
- 3.3 Client访问处理流程
- 3.3.1 Remote模式下的SessionBean处理流程
- 3.3.2 Local 模式下的SessionBean处理流程
- 3.4 基于EJB2.1的Demo
- 3.5 SessionBean分类
- 3.5.1 Stateful
- 3.5.2 Stateless
- 3.5.3 Singleton
- 3.6 SessionBean生命周期
- 3.6.1 Stateful
- 3.6.2 Stateless
- 3.6.3 Singleton
- 4、EntityBean
- 5、MessageDrivenBean
- 6、EJB vs Spring
1、EJB 概念
EJB是Enterprise Java Bean的简称,翻译后应该是:企业级Java组件,也可以称为分布式组件。它是为分布式商业服务提供了一个思想超前的、提供了安全和事务的、通用的平台。
2、EJB体系结构
EnterpriseBean和Serializable接口一样,是一个标记性接口。用于标记一个类为一个Bean(豆,组件)。它有三种实现:SessionBean,EntityBean,MessageDrivenBean。
SessionBean:它是对业务逻辑的封装,类似于我们经常写的Service层。它可以以local, remote, webservice 服务的方式被client调用。
EntityBean:它是对数据库对象的封装,一个EntityBean,就是数据库的一条记录。
MessageDrivenBean:一个messageDrivenBean其实就是一个javax.jms.MessageListener。在JMS中有MessageConsumer,它支持两种接收消息的方式:同步接收采用MessageConsumer#receive()方法,异步接收则是为MessageConsumer设置一个MessageListener,一旦接收到消息,就调用listener#onMessage()。
3、SessionBean
它是对业务逻辑的封装,类似于我们经常写的Service层。它可以以local, remote, webservice 服务的方式被client调用。
3.1 SessionBean服务端组件
SessionBean服务端有三大组件Home、EJbObject、SessionBean。
SessionBean是我们编写业务逻辑的地方。譬如数据库操作,进行计算等等。但是它对于客户端是不可见的,一个SessionBean实例的创建、销毁、激活、钝化等都是由EJB容器来管理的。
EJBObject:你可以将EJBObject看作是SessionBean对象的Proxy。需要将你的业务方法同样在EJBObject中复制一份。例如有一个HelloSessionBean#sayHello(str) 业务,如果要将该业务方法暴露出去给Client使用,与之对应的HelloEJBObject中必然得包含#sayHello(str)方法。也就是说Client需要使用EJBObject来达到与SessionBean交互的。
Home:这个名字起的怪异,我们可以将其理解为一个SessionBean的Factory。EJB容器通过Home对象来创建SessionBean对象,并装配出它的代理对象(EJBObject对象)。这是它的唯一用途。
3.2 Remote与Local
对于Home,和EJBObject,它们俩个都分为两类:Remote,Local。
Remote模式的,主要用于不在同一个JVM进程里,而在同一个进程里使用时,只需要使用Local模式的即可,这样选择自然是为了性能考虑。
Home、EJBObject我们看到的只是接口,谁来创建他们呢?
这个问题其实很简单了,之前已说了EJBObject是一个Proxy,我们不难想到,基于动态代理或者字节码技术,就可以动态的(具体来说就是部署EJB时)生成Home、EJBObject的实现类。
此外,在构建完Home的实现类之后,就会创建出一个单例的Home对象,并将其注册到JNDI服务器上。这样客户端就可以通过jndi服务lookup到该Home的引用。
EJBObject对象,是在client通过EJBHome#create() 或者EJBLocalHome#create()时由服务端的Home对象创建一个EJBObject的实例,并返回它的引用给客户端。
3.3 Client访问处理流程
在上面已经说明Home对象在ejb应用部署时就会创建出一个单例,并注册到JNDI服务器上。
客户端访问一个业务的流程是怎样的呢?
3.3.1 Remote模式下SessionBean 的访问流程
|
1、客户端通过JNDI获取到Home对象(EJBHome)的引用 2、客户端使用homeRef#create()方法来创建出EJBObject的Stub。 2.1)客户端底层使用Socket通信将次过程发给服务端Skeleton。 2.2)Skeleton调用服务端的Home对象的create方法,分配SessionBean对象(可能是新创建一个,也可能是从对象池中取一个,具体怎样依赖于是否是Stateful的),同时为该SessionBean对象生成一个代理对象(EJBObject实例),然后返回代理对象的引用。 2.3)客户端拿到EJBObject的引用就是Stub对象。 3、客户端访问业务 3.1) 客户端底层使用Socket通信将次过程发给服务端Skeleton。 3.2)Skeleton根据请求找到该EJBObject,调用与之关联的SessionBean的相应的业务。返回结果 3.3)客户端得到调用结果 |
3.3.2 Local模型下SessionBean的访问流程
|
1、客户端通过JNDI获取到Home对象(EJBLocalHome)的引用 2、客户端使用homeRef#create()方法来创建出EJBLocalObject(怎么创建也要依赖于是否的Stateful的) 3、客户端访问业务 |
很容易对比出Local模式性能好在哪了。
在EJB3 中,会有更方便的写法了,用@EJB即可搞定。
3.4 基于EJB2.1的Demo

1)编写业务接口 AdviceService
public interface AdviceService {
String getAdvice(String str) throws RemoteException;
}
2) 编写SessionBean类
public class AdviceServiceImpl implements AdviceService, SessionBean {
public String getAdvice(String str){
return “Advice” + str;
}
// 其他的ejbCreate,ejbActivate等不展示
}
3)指定EJBObject接口
public interface AdviceServiceEjbObject extends EJBObject, AdviceService{
}
4) 指定Home接口
public interface AdviceServiceFactory extends EJBHome{
public AdviceServiceEjbObject create() throws RemoteException, CreateException;
}
5) 在ejb-jar.xml中配置要暴漏的SessionBean:

ejb-jar.xml是放在META-INF目录下。
6)关联到jndi服务

这一步是WebLogic服务器上配置的,其他的JavaEE服务器应该也有类似的机制。
7)打包部署到JavaEE服务上。
8)客户端调用

代码中的JndiResources.getProperty(“ejb.advice”) 用于取得 xxx.properties文件中配置的JNDI名称,这个JNDI名称,就是第6步映射的JNDI名称。EjbEnvs.getEjbEnv()方法,是为了得到在不同的JavaEE服务器上的InitialContext的配置,这属于测试用例的配置。
例如:

然后就是通过JNDI获取的Home Reference,然后调用create获取EJBObject的Stub,最后调用业务方法。
3.5 SessionBean 分类
在上面说的通过Home对象的create过程中,有个SessionBean创建,是要依赖于是否是Stateful的。也就是说SessionBean会区分为:Stateless, Stateful,在EJB3.1加入Singleton的。
3.5.1 Stateful SessionBean
对于一个普通的Java对象而言,它的属性就是它的状态。而Stateful SessionBean是与Client相关联的,也就是说一个Client会有一个SessionBean与之对应。这样的SessionBean可以存活在与Client的整个会话期间。当一个Client终端时,SessionBean才会与该Client失去联系。
SessionBean的state(也就是对象的字段)会在整个会话期间保留,直到会话关闭。
3.5.2 Stateless SessionBean
无状态的SessionBean,它的state只会存在于业务方法调用期间,一旦方法调用完毕,这些字段就会失效。无状态的SessionBean不会与某个Client关联。
3.5.3 Singleton SessionBean
单例的SessionBean,那么对于一个应用,只会存在一个这样的对象。它是可以被多个Client并发的调用的。Stateful、Stateless SessionBean,在同一时间都只能为一个Client服务,它们是采用对象池技术实现的。
|
Stateful |
Stateless |
Singleton |
|
|
与Client关联 |
是 |
否 |
否 |
|
单个实例支持并发访问 |
否 |
否 |
是 |
|
对象管理 |
LRU等缓存 |
对象池 |
单例 |
|
发布为WebService |
否 |
是 |
是 |
|
存活周期 |
整个会话 |
单个业务方法调用 |
应用 |
|
单个实例被多个Client重用 |
不会 |
可以 |
可以 |
3.6 SessionBean 生命周期
3.6.1 Stateful SessionBean
对于Stateful SessionBean。当Client通过Home Ref执行create时,服务端的Home会直接创建一个代理对象(EJBObject/EJBLocalObject实例),和一个SessionBean(会被EJB容器决定是否作为钝化状态)。

图中上边的:1)2)3)4)分别代表了:
1) SessionBean 对象的创建
2) 依赖注入
3) 执行@PostConstruct
4) 执行init方法、或者ejbCreate方法。
此时对象创建完毕,bean变为ready状态,也会返回给client一个proxy的stub。但EJB容器仍然要对这个SessionBean的状态定期进行处理,通常会基于LRU缓存对cache中bean进行passivate处理。Passivate之前、activate之后会有相应的回调方法执行。
图中下边的1)2)代表了:
1) Client调用@Remove
2) 服务端调用@PreDestory
之后一个SessionBean就被销毁了,等待它的将是JVM的GC。
3.6.2 Stateless SessionBean
对于Stateless SessionBean,当Client使用Home Ref创建EJBObject(或者EJBLocalObject)对象时,并不会创建一个关联的Session Bean。当调用业务时,才会从SessionBean Pool选择一个空闲的处理业务。它是不存在passivate, activate的转换的。

3.6.3 Singleton SessionBean
上文说了,它的生命周期在整个应用期间。

4、EntityBean
可以把EntityBean看做是数据库记录。数据库的访问才用JPA(Java Persistence Abstract,参见javax.persistence.*)
分为CMP(Container managed Persistence),BMP (Stateless SessionBean managed Persistence)两种,他们支持事务(声明式事务、编程式事务)
事务支持扁平式事务,嵌套式事务。学过Spring的人应该都了解的,相信Spring的作者肯定对EJB了解极深。
5、MessageDrivenBean
在前面已经说明,他就是一个MessageListener。

前文已经说明了一切。这里只说一下MessageDrivenBean的生命周期:

6、EJB vs Spring
网上充斥着大量的EJB已死、Spring替代EJB的文章。我就纳闷了,EJB是做分布式业务调用的,Spring是做IOC的,两者有什么可比的呢?这是我在了解EJB之前的一个疑问。
通过对EJB做了个简单的了解,我终于知道他们在比什么了:
AOP & IOC
通过上面对EJB的阐述,我们从Bean的生命周期中,我们可以看到,EJB容器可以说是IOC的先驱。在后续的版本中EJB已经补齐了IOC的支持。
EJB中对SessionBean调用之前,还有做一些其他事情, 譬如Security、Transaction。这完完全全就是AOP的应用嘛。
通过上面的例子知道,要部署一个EJB组件,确实挺麻烦的,还要写那么多程序化的接口(Home和EJBObject)。EJB3.0之后支持了注解,释放了这个繁琐的过程。也就是说EJB的笨重,应该是Spring等一大批IOC容器(Spring,Guice,HK2)产生的原因了。
只能说EJB在某些场合(Local模式下)下被Spring替代。
EJB:快速入门的更多相关文章
- Java Web快速入门——全十讲
Java Web快速入门——全十讲 这是一次培训的讲义,就是我在给学生讲的过程中记录下来的,非常完整,原来发表在Blog上,我感觉这里的学生可能更需要. 内容比较长,你可以先收藏起来,慢慢看. 第一讲 ...
- Java基础-SSM之Spring快速入门篇
Java基础-SSM之Spring快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java ...
- Shiro官方快速入门10min例子源码解析框架2-Session
Shiro自身维护了一套session管理组件,它可以独立使用,并不单纯依赖WEB/Servlet/EJB容器等环境,使得它的session可以任何应用中使用. 2-Session)主要介绍在quic ...
- Spring Data JPA —— 快速入门
一.概述 JPA : Java Persistence API, Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. Spring D ...
- wildfly(JBoss AS)应用服务器快速入门
什么是wildfly JBoss AS 从8版本起名为wildfly.Wildfly是一个开源的基于JavaEE的轻量级应用服务器.可以在任何商业应用中免费使用. WildFly是一个灵活的.轻量的. ...
- SpringBoot简介与快速入门
一.SpringBoot简介 1.1 原有Spring优缺点分析 1.1.1 Spring的优点分析 Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE ...
- SpringBoot基础篇-SpringBoot快速入门
SpringBoot基础 学习目标: 能够理解Spring的优缺点 能够理解SpringBoot的特点 能够理解SpringBoot的核心功能 能够搭建SpringBoot的环境 能够完成applic ...
- SpringBoot快速入门(实战篇一)
SpringBoot快速入门(一) 一SpringBoot简介 1.spring开发经历的阶段 Spring 诞生时是 Java 企业版(Java Enterprise Edition,JEE,也称 ...
- Web Api 入门实战 (快速入门+工具使用+不依赖IIS)
平台之大势何人能挡? 带着你的Net飞奔吧!:http://www.cnblogs.com/dunitian/p/4822808.html 屁话我也就不多说了,什么简介的也省了,直接简单概括+demo ...
- SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=》提升)
SignalR快速入门 ~ 仿QQ即时聊天,消息推送,单聊,群聊,多群公聊(基础=>提升,5个Demo贯彻全篇,感兴趣的玩才是真的学) 官方demo:http://www.asp.net/si ...
随机推荐
- 在vi按了ctrl+s后
习惯了在windows下写程序,也习惯了按ctrl+s 保存代码,在用vi的时候,也习惯性的按ctrl+s 结果就是如同终端死掉了一样. 原来: ctrl+s 终止屏幕输出(即停止回显),你敲的依然有 ...
- mysql数据库第一弹
mysql(一) sql语句 sql是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言. 在使用它时,只需要 ...
- Instrumentation 框架简介
原文地址:http://www.cnblogs.com/xirihanlin/archive/2010/06/15/1758677.html Android提供了一系列强大的测试工具,它针对Andro ...
- View处理常用方法封装
处理View常用的一些方法:Drawable和Bitmap互相转换,Bitmap改变大小,dp.px互相转换,sp.px互相转换,根据Id查找Drawable,获取屏幕大小等方法. import an ...
- 基于 HTML5 Canvas 的简易 2D 3D 编辑器
不管在任何领域,只要能让非程序员能通过拖拽来实现 2D 和 3D 的设计图就是很牛的,今天我们不需要 3dMaxs 等设计软件,直接用 HT 就能自己写出一个 2D 3D 编辑器,实现这个功能我觉得成 ...
- Play-With-Docker在chrome上的插件
一键使用PWD 在chrome扩展中,找到"Play With Docker"插件,并安装在chrome浏览器中 进入hub.docker.com网站,搜索熟悉的docker镜像. ...
- 找出共同好友 - 数据挖掘 - Scala版
大家好,关于“找出共同好友”的算法,网上有不少语言的实现,今天有空之余,自己研究了下Scala算法的写法 完整代码可以参考Git地址:https://github.com/benben7466/Spa ...
- 浅谈Android中Serializable和Parcelable使用区别
版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.概述 Android开发的时候,我们时长遇到传递对象的需求,但是我们无法将对象的引用传给Activity或者Fragment,我们需要将这些对象 ...
- 【NOIP2012提高组】同余方程
https://www.luogu.org/problem/show?pid=1082 方程可化为ax+by=1. 用扩展欧几里得算法得到ax'+by'=gcd(a,b)的一组解后,可得x=x'/gc ...
- springboot学习(三)——http序列化/反序列化之HttpMessageConverter
以下内容,如有问题,烦请指出,谢谢! 上一篇说掉了点内容,这里补上,那就是springmvc的http的序列化/反序列化,这里简单说下如何在springboot中使用这个功能. 使用过原生netty ...