`

EJB 知识与运行环境设置

    博客分类:
  • EJB
阅读更多
21.    依赖注入

当 EJB 需要使用其他 EJB 或资源的时候,必须通过 JNDI 查找或者注入注释来实现,而不能使用 new object 的方式,因为 EJB 实例的创建与销毁都是由容器进行管理的。

 

22.    ENC 注册项

1) EJB 容器有一个自己的内部注册表( internal registry ),称为 Enterprise Naming Context ( ENC )。容器在 ENC 中维护某些外部环境的应用,可以认为 ENC 是容器的私人地址簿。先往 ENC 中登记资源,然后再从 ENC 中获取资源的引用。

2) 要往 ENC 添加引用的注册项,可以通过:

l            ejb-jar.xml (用于 EJB 模块)

l            web.xml (用于 WEB 模块)

l            注入注释

3) 使用 ejb-jar.xml 添加注册项:

< enterprise-beans >

       < session >

           < ejb-name > InjectionTestBean </ ejb-name >

           < ejb-ref >

              < ejb-ref-name > ejb/HelloWorldBean1 </ ejb-ref-name >

              < ejb-ref-type > Session </ ejb-ref-type >

              < remote > cn.gengv.ejb3ex.HelloWorld </ remote >

              < ejb-link > HelloWorldBean </ ejb-link >

           </ ejb-ref >

           < ejb-local-ref >

              < ejb-ref-name > ejb/HelloWorldBeanL </ ejb-ref-name >

              < ejb-ref-type > Session </ ejb-ref-type >

              < local > cn.gengv.ejb3ex.HelloWorldLocal </ local >

              < ejb-link > HelloWorldBean </ ejb-link >

           </ ejb-local-ref >

       </ session >

       < session >

           < ejb-name > InjectionTestBean3 </ ejb-name >

           < ejb-ref >

              < ejb-ref-name > ejb/HelloWorldBean3 </ ejb-ref-name >

              < ejb-ref-type > Session </ ejb-ref-type >

              < remote > cn.gengv.ejb3ex.HelloWorld </ remote >

              < ejb-link > HelloWorldBean </ ejb-link >

           </ ejb-ref >

       </ session >

    </ enterprise-beans >

 

4) 使用 @EJB 注释添加注册项

@Stateless

@EJB (

           name = "ejb/HelloWorldBean2" ,

           beanName = "HelloWorldBean" ,

           beanInterface = HelloWorldLocal. class

)

public class InjectionTestBean2 implements InjectionTestLocal {

}

 

5) 对应关系:

单独使用 ejb-jar.xml 和 @EJB 注释都可以在 ENC 中添加注册项。

l            @EJB 的 name()  ==>  <ejb-ref-name>

l            @EJB 的 beanName()  ==>  <ejb-link>

l            @EJB 的 beanInstance()  ==>  <remote> 或 <local>

 

23.    获取 ENC 中的资源引用

1) 两种途径: JNDI 查找 和 @EJB 注入

2) JNDI 查找:

l            使用 InitialContext 的 lookup() 方法,根据注册项引用名称进行 JNDI 查找;

l            <ejb-ref-name> 或 @EJB.name() ,注册的应用名称,都是相对于 java:comp/env 上下文的;例如:

HelloWorld hw = (HelloWorld)ctx.lookup("java:comp/env/ejb/HelloWorldBean1");

l            注意,在不同的 EJB 中调用 lookup , java:comp/env 会被解析为不同的上下文环境。例如在 EJB1 中调用 lookup(“java:comp/env”) 获取的就是 EJB1 的 ENC ;在 EJB2 中调用 lookup(“java:comp/env”) 获取的就是 EJB2 的 ENC 。

3) @EJB 注入:

l            只要给成员变量或者 setter 方法上标注 @EJB 注释, EJB 容器就会在 Bean 实例被创建时,自动往 Bean 的 ENC 中添加一个注册项,同时把 EJB 的引用直接注入成员变变量或 setter 方法中。

l            依赖注入只能用于本地命名服务中,因此不能注入远程服务器对象。

 

24.    @EJB 依赖注入

1) @EJB 的属性:

l              name() :表示被引用的 EJB 的 JNDI ENC 注册项名称,该名称相对于 java:comp/env 上下文。

l              beanInterface() :指定使用的 Bean 接口。该属性通常用来区分所使用的 EJB 引用是远程还是本地的。如果 @EJB 用在 Bean 类级别,则必须指定该属性;如果用在成员变量或者 setter 方法上时,可以省略。(个人理解,如果用在类级别而不指定该属性,则 @EJB 没有任何依据,来指定何种接口,隐式添加到 ENC 注册项;而在成员变量或方法级别, @EJB 至少可以通过成员变量的类型或 setter 的参数类型,指定该接口类型,隐式添加到 ENC 注册项)

l              beanName() :指定被引用的 EJB 的名称,其值与 @Stateless.name() 、 @Stateful.name() 或 ejb-jar.xml 中 <ejb-name> 元素的值相等。

l              mappedName() :表示 EJB 的全局 JNDI 名称,而全局 JNDI 名称与容器厂商有关,不利于移植,因此不推荐使用,

2) @EJB 注释工作时,会自动引发容器在 JNDI ENC 中为被注入的元素创建一个注册项。

l            注册项名称:由 @EJB.name() 指定,如果没有指定名称,则容器会根据被注入的成员变量或 setter 方法的名称,设置 ENC 名。默认的 ENC 名称由被注入的类的全限定名和成员变量或方法的基础名组成。例如:

cn.gengv.ejb3ex.impl.InjectionTestBean/hw

l            注册项引用接口:由 @EJB.beanInterface() 指定,如果没有指定,容器会根据被注入成员变量类型或 setter 方法的参数类型来设定。

l            注册项引用的 EJB 名称:由 @EJB.beanName() 指定。

l            综上情况,使用 @EJB 注入而自动产生的注册项应该与如下 xml 设置的效果相同:

< enterprise-beans >

< session >

< ejb-name > InjectionTestBean </ ejb-name >

< ejb-ref >

< ejb-ref-name >

cn.gengv.ejb3ex.impl.InjectionTestBean/hw

</ ejb-ref-name >

< ejb-ref-type > Session </ ejb-ref-type >

< remote >

cn.gengv.ejb3ex.HelloWorld

</ remote >

< ejb-link > HelloWorldBean </ ejb-link >

</ ejb-ref >

</ session >

</ enterprise-beans >

 

25.    @EJB 注释属性的应用场合

1) 不带任何属性

当接口在 EJB-JAR 内只被一个 Bean 类使用的时候,可以这样引用。

对于 @EJB HelloWorldLocal hw;

l            唯一标识符就是 HelloWorldLocal 接口,应用服务器首先在注入方的 EJB-JAR 中查找使用 HelloWorldLocal 作为本地或远程接口的 EJB 类。如果有多个 EJB 类使用了该接口,则容器会抛出一个部署异常。

l            如果 EJB-JAR 作为 EAR 的一个模块被部署,则容器也会在其他 EJB-JAR 中查找使用了该接口作为本地或远程接口的 EJB 类。同样,如果多于一个,也会引发异常。

l            如果容器没能在 EAR 中找到该 EJB 引用,则它会继续在其他全局 EJB-JAR 中继续寻找。

l            如果指定了 beanName() , JBoss 会遵循相同的过程,但它使用的唯一标示符是 beanName() 的值;如果指定了 mappedName() ,则 JBoss 不会进行任何搜索,而是根据 mappedName 值,直接从全局 JNDI 中获取 EJB 引用。

 

2) 带 beanName() 属性

l            当业务接口被多个 Bean 类使用时,则必须指定 beanName 。否则,在 @EJB 注入注释工作时,容器无法判断使用哪个 Bean 类名称作为注册项引用 EJB 名称。(相当于无法确定用哪个 Bean 名称作为 <ejb-link> )

l            如果引用的 EJB 不在 InjectionBean 所在的 JAR 文件中,而在 .ear 的其他 JAR ,则可以使用下面形式进行引用:

@EJB(beanName=”zhenxi.jar#HelloBean”) LocalHello helloworld;

 

3) 带 name() 属性

l            如果业务接口只被一个 Bean 类用作本地或者远程接口,则使用 @EJB(name=”ejb/HelloWorld”) HelloWorld hw 与 @EJB HelloWorld hw 效果一样;不同的是,前者在 ENC 的名称是 java:comp/env/ejb/HelloWorld ;而后者为 cn.gengv.ejb3ex.impl.InjectionTestBean/hw 。

l            如果业务接口被多个 Bean 类使用,要想单单只是用 name() 属性,则必须在 ejb-jar.xml 中配置注册项(在 EJB3.0 中, xml 部署描述文件的优先级高于注释,可以使用 xml 覆盖注释的配置)。如果不想配置 xml ,那就得一并使用 beanName 属性。

 

【个人观点】

实际上, name() 属性与是否有多个 Bean 类使用同一个业务接口,没多大关系。真正关系到是否一个业务接口被多个 Bean 类使用的,应该是 beanName() 属性。 要想使用注入,隐式地 为 ENC 添加注册项,不论用到或没用到 @EJB 的什么属性,真遇到一个业务接口被多个 Bean 类使用的时候,也照样还得 beanName() 出马来解决判断问题,否则容器不可能知道应该用哪个 Bean 类。

 

4) 带 mappedName() 属性

l            容器会根据 mappedName() 的值,直接从全局 JNDI 中查找 EJB 引用,容器无需执行像 beanName() 属性那样的搜索规则。

l            mappedName() 属性值与厂商有关,可能会带来移植问题,应避免使用。

 

26.    补充要点

1) 可以将无状态会话 Bean 注入到有状态或无状态会话 Bean 中;也可以将有状态会话 Bean 注入到有状态会话 Bean 中;但不应该将有状态会话 Bean 注入到无状态会话 Bean 中。

2) 如果被注入的 jar 与使用者不在同一个 jar 中,例如使用者在 DependencyInjection.jar 中,而被注入的 EJB 在 HelloWorld.jar 。 JBoss 在启动时,会按默认发布顺序先发布 DependencyInjection.jar ,后发布 HelloWorld.jar 。然而,由于 DependencyInjection.jar 中用到了 HelloWorld.jar 中的 EJB ,所以会抛出找不到类的异常,导致 DependencyInjection.jar 发布失败。解决办法是:

修改 JBoss 的 /server/default/conf/jboss-service.xml 文件,找到

<attribute name="URLComparator">

org.jboss.deployment.DeploymentSorter

</attribute>

 

<!--

<attribute name="URLComparator">org.jboss.deployment.scanner.PrefixDeploymentSorter

</attribute>

-->

修改成:

<!--

<attribute name="URLComparator">

org.jboss.deployment.DeploymentSorter

</attribute>

-->

 

<attribute name="URLComparator">org.jboss.deployment.scanner.PrefixDeploymentSorter

</attribute>

然后给 jar 文件编号,格式为 01_XXX.jar ,如 01_HelloWorld.jar 、 02_DependencyInjection.jar , JBoss 会按照编号顺序发布 jar 文件。

 

27.    资源类型的注入

1) @javax.annotation.Resource 注释用来注入外部资源类型。其工作过程与 @EJB 相同,也是先往 JNDI ENC 添加一个指向资源引用的注册项,然后把资源引用注入到成员变量或者 setter 方法中。

2) @Resource 注释的属性

l            name() :用于指定外部资源的 JNDI ENC 名,该名称是相对于 java:comp/env 的。

l            type() :用于指定资源对应的 Java 类型。

l            mappedName() :指定资源的 JNDI 名,该值与厂商有关。

l            shareable() :指定资源是否共享,默认为 true 。

l            authenticationType() :指定有谁来负责权限验证,其值可以是 CONTAINER 或 APPLICATION ,默认值为 CONTAINER ,即容器自动执行所需验证工作。如为 APPLICATION ,则 Bean 类需要在使用资源之前自行验证。

 

28.    注入与继承

1) 被注入到使用者中的 EJB ,可以被使用者的子类继承;

2) 在使用者的子类中,也可以通过重定义成员变量或者重写( override ) setter 方法来更改注入的资源。

3) 应当注意,注入的继承关系,是由类的继承关系产生出来的。

 

29.    自定义注入注释

可以通过自定义注入注释,并使用拦截器拦截生命周期事件的回调方法(例如 @PostConstruct ),利用 Java 反射机制,来实现注入。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gengv/archive/2009/07/17/4358264.aspx
分享到:
评论

相关推荐

    EJB 知识与运行环境设置(笔记)

    ### EJB知识与运行环境设置 #### EJB概述 企业JavaBeans (EJB) 是Java平台对企业级应用程序组件的一种标准化模型。它属于Java EE规范的一部分,主要用于构建可移植的企业级应用。EJB定义了三种主要的Bean类型: 1...

    EJB3.0学习之运行环境配置

    ### EJB3.0 学习之运行环境配置详解 #### 一、EJB3.0简介 EJB(Enterprise JavaBeans)3.0是Java企业级应用开发的一个重要组成部分,它代表了Java平台在服务器端组件化方面的最新进展。EJB3.0简化了前几代版本中...

    实战EJB 实战EJB 实战EJB

    ### 实战EJB知识点解析 #### 一、企业JavaBeans (EJB) 技术概览 **什么是企业JavaBeans技术?** 企业JavaBeans (EJB) 是Java平台上的服务器端组件模型,专为构建可扩展、可靠且跨平台的企业级应用程序而设计。...

    yeclipse7.0+JBoss5.0测试EJB3.0环境搭建过程详解

    在深入探讨如何在yeclipse7.0与JBoss5.0环境下构建和测试EJB3.0应用之前,让我们先了解一些背景知识。EJB(Enterprise JavaBeans)是Java平台的一部分,用于开发和管理基于组件的企业级应用程序。EJB3.0引入了大量...

    EJB学习

    掌握EJB知识对于开发大型企业级应用至关重要,它可以帮助开发者构建可扩展、高可用性的系统。通过学习EJB,开发者可以更好地理解Java EE框架,提升在分布式系统开发中的能力。同时,了解EJB也是向更高级的技术如...

    EJB3.1与JBoss7.1.1在eclipse的实现

    - JBoss7.1.1:JBoss应用服务器的具体版本号,是Java EE应用的运行环境。 2. 安装JBoss - 解压下载的JBoss压缩文件到本地目录,并注意目录名不要包含中文和空格,以免出现路径问题。 - 配置JBoss环境变量JBOSS_...

    EJB基础知识2---EJB资料

    容器为bean提供了运行时环境,使得开发人员无需关注底层实现细节,专注于编写业务逻辑。 **EJB版本发展** EJB标准经历了多个版本的发展,从EJB 1.0到最新的EJB 3.x(包括EJB 3.1和EJB 3.2)。每个新版本都引入了...

    精通EJB2.0 书籍源码

    在EJB2.0中,数据库表通常对应实体bean的持久化状态,EJB.sql可以用于快速设置数据库环境。 6. **README.TXT**:这是一个标准的文本文件,通常包含项目简介、安装指南或使用注意事项。在EJB2.0源码中,这个文件可能...

    东北大学EJB实验报告

    1. **环境配置**:设置Java EE开发环境,包括JDK、EJB容器(如Glassfish或JBoss)、集成开发环境(IDE,如Eclipse或IntelliJ IDEA)。 2. **创建EJB组件**:使用IDE创建EJB项目,定义会话Bean、实体Bean或消息驱动...

    tuxedo EJB

    ### tuxedo EJB知识点详解 #### 一、EJB技术概述 **EJB**(Enterprise JavaBeans)作为**J2EE**(Java 2 Enterprise Edition)架构的重要组成部分,主要用于实现企业级应用中的业务逻辑层。EJB的设计目的是为了简化...

    EJB实例工程代码

    2. **容器管理**:EJB容器是运行EJB组件的环境,它提供了诸如事务管理、安全、资源连接等服务。开发者只需关注业务逻辑,容器负责其他细节。 3. **接口和实现**:EJB组件通常定义了至少一个接口,客户端通过该接口...

    WebSphere环境下EJB编程

    - **EJB容器**:WebSphere为EJB提供了一个运行环境,包括容器来管理Bean的生命周期、提供服务如事务、安全性等。 - **EJB部署描述符**:通过ejb-jar.xml文件配置EJB的行为,如接口定义、事务策略、安全角色等。 - **...

    Weblogic下ejb配置

    本篇文章将深入探讨在WebLogic Server环境下配置EJB的相关知识。 一、EJB概述 EJB是一种组件模型,用于在Java EE环境中实现业务逻辑。它有三种主要类型:会话bean(Session Beans)、实体bean(Entity Beans)和...

    ejb用到得全部包

    它包含了EJB容器、JNDI(Java Naming and Directory Interface)、JMS、JTA(Java Transaction API)等服务的实现,使得开发者可以在JBoss环境中部署和运行EJB应用程序。 EJB的核心知识点包括: - **会话bean**:...

    EJB课件

    本课件主要涵盖了EJB的核心概念,EJB-QL语句,Jboss应用服务器的安装配置,以及编写与部署EJB程序的相关知识点。 首先,EJB-QL(Enterprise JavaBeans Query Language)是EJB的查询语言,类似于SQL,但用于对象关系...

    东北大学EJB实验

    6. **部署与运行**:将EJB应用部署到应用服务器(如Tomcat、WildFly等),验证功能是否正常工作。 通过这个实验,学生不仅能学习到EJB的基础知识,还能了解如何在实际项目中使用EJB来构建分布式、事务处理的系统。...

    传智播客ejb3.0教学ppt

    #### 九、EJB 3.0的运行环境 - **JDK版本要求**:EJB 3.0应用需要在JDK 1.5以上的环境中运行。 - **下载资源**:可以通过Sun官方网站下载所需的JDK版本。 通过以上总结可以看出,EJB 3.0作为一种成熟的企业级应用...

Global site tag (gtag.js) - Google Analytics