EJB基本概念和使用

一、EJB是什么?

  1. EJB是sun的JavaEE服务器端组件模型,是一种规范,设计目标与核心应用是部署分布式应用程序。
  2. EJB2.0过于复杂,EJB3.0的推出减轻了开发人员进行底层开发的工作量,它取消或最小化了很多(以前这些是必须实现)回调方法的实现,并且降低了实体Bean及O/R映射模型的复杂性。
  3. EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力承诺的组件。

二、EJB3.0新特性

相比EJB3以前的版本而言,增加了两个新特性:元数据注解(Annotation) 和依赖注入(Injection),而元数据注解以最大限度的使部署描述符从冗余繁杂中脱离出来。

三、EJB体系结构

EnterpriseBean和Serializable接口一样,是一个标记性接口。用于标记一个类为一个Bean。它有三种实现:SessionBeanEntityBeanMessageDrivenBean

SessionBean:它是对业务逻辑的封装,类似于我们经常写的Service层。它可以以local, remote, webservice 服务的方式被client调用。

EntityBean:它是对数据库对象的封装,一个EntityBean,就是数据库的一条记录。

MessageDrivenBean:一个messageDrivenBean其实就是一个javax.jms.MessageListener。在JMS中有MessageConsumer,它支持两种接收消息的方式:同步接收采用MessageConsumer#receive()方法,异步接收则是为MessageConsumer设置一个MessageListener,一旦接收到消息,就调用listener#onMessage()。

四、SessionBean

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对象)。这是它的唯一用途。

2、Remote与Local

对于Home,和EJBObject,它们俩个都分为两类:Remote,Local。

Remote模式的,主要用于不在同一个JVM进程里,而在同一个进程里使用时,只需要使用Local模式的即可,这样选择自然是为了性能考虑。

3、Client访问处理流程(很容易看出Local性能好在哪里)

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.2 Local模型下SessionBean的访问流程

1、客户端通过JNDI获取到Home对象(EJBLocalHome)的引用

2、客户端使用homeRef#create()方法来创建出EJBLocalObject(怎么创建也要依赖于是否的Stateful的)

3、客户端访问业务

五、常用注解

**@Stateless:**标记类把Java类声明为一个无状态会话bean

**@EJB:**表示注入实例,EJB注入和Resource注入相比,EJB注入只是针对于EJB而言,而Resource注入即是对所有的文件都可以进行注入。

**@Remove:**为会话 Bean 声明远程业务接口。用在接口上时,将该接口指定为远程业务接口。在这种情况下,不提供任何 value()。用在方法上,通过这个注解来说明在调用这个方法之后bean的实例将被清除掉。

**@Local:**用在 Bean 类上时,为会话 Bean 声明本地业务接口。用在接口上时,将该接口指定为本地业务接口。在这种情况下,不提供任何 value()。如:@Local(LawsuitService.class)

**@Stateful:**有状态会话 Bean 的组件定义注释。

**@Timeout:**指定无状态会话 Bean 类或消息驱动 Bean 类上接收该 Bean 的 EJB 计时器过期的方法。

**@TransactionAttribute:**在 TYPE-level 应用时,为会话或消息驱动 Bean 的所有业务方法指定默认事务属性。在方法级应用时,仅为该方法指定事务属性。

如:@TransactionAttribute(TransactionAttributeType.SUPPORTS)、

@TransactionAttribute(TransactionAttributeType.REQUIRED)。

**@Interceptors:**声明类或方法的拦截器的有序列表。

**@Lock:**方法声明一个并发锁的单例bean具有容器管理的并发。

**@Schedule(排程器):**计划时间为自动建立一个超时计划基于一个时间表达式。

**@Startup:**标记一个单例在应用初始化期间。

**@ConcurrencyManagement:**声明单例或有状态bean的并发管理类型

六、EJB的使用

1.依赖导入:

pom.xml

       
        
            javax
            javaee-web-api
            7.0
            provided
        
    

2.代码示例:

@Stateless
//不写默认本地@Local

public class ProdMgr {

    @EJB//注入prodService,如果出现多个ProdService接口的实现类可以使用name属性区分
    private ProdService service;


    public String getName() {
        
       String name = service.prod.getName();
        
        return name;
    }

你可能感兴趣的:(EJB)