基本的EJB参考,注入和查找

在本系列的第一部分中 ,我们介绍了Enterprise JavaBeans v。3.0规范提供的机制,用于定义EJB组件,声明对EJB的引用并通过依赖项注入或程序化JNDI查找将它们连接起来。

在此博客文章中,我们将研究一些基本示例以了解如何使用EJB API。

基本EJB

EJB本质上是带有一些额外EJB元数据的POJO。 可以通过使用EJB批注或通过标准部署描述符来提供将其部署为EJB组件所需的元数据。 以下类实现了一个非常基本的无状态会话EJB:

package es.reacts;import javax.ejb.Stateless;@Stateless(name = "UniqueLocalSessionEJB")
public class UniqueLocalSessionEJBBean implements UniqueLocalBusinessInterface {public UniqueLocalSessionEJBBean() {}public String sayLocalHello() {return this.getClass().getName() + "::" + "Local hello.";}
}

正如您可能从我们以前的博客文章中所回顾的那样, @Stateless批注用于定义无状态会话bean。 可选的name元素用于定义会话bean 名称 。 该元素类似于标准部署描述符的<ejb-name />元素。 此元素默认为bean类(UniqueLocalSessionEJBBean在上面的例子中),和上述使用它的示例的非限定名称重新命名bean来UniqueLocalSessionEJB。

由于我们使用@Stateless批注,因此不再需要在部署描述符中声明EJB。

在此示例中,我们假设EJB打包在EJB模块中,该模块取决于包含其业务接口定义的模块(如以下部分所述)。

业务接口

每个EJB都实现一个或多个业务接口。 业务接口可以是本地远程的 。 两种类型的业务接口之间最重要的区别可以归纳如下:

  • 本地业务接口对其方法使用按引用传递语义,并且方法调用不能跨越JVM边界。 本地业务接口仅对被调用方的相同应用程序和JVM实例中的调用方可用。
  • 远程业务接口对其方法使用按值传递语义,并且方法调用可以跨越JVM边界。 远程业务接口可用于被呼叫者应用程序之外的呼叫者。

在前面的示例中,业务接口UniqueLocalBusinessInterface声明如下:

package es.reacts;import javax.ejb.Local;@Local
public interface UniqueLocalBusinessInterface {String sayLocalHello();
}

在EJB v。3.0世界中,业务接口只是用@Local@Remote批注进行批注的普通Java接口。

包装业务接口

在此示例中,我们假设EJB业务接口打包在EJB模块依赖的JAR文件中。 由于EJB客户端仅依赖EJB业务接口,因此,将业务接口打包在一个单独的库中是一个好习惯,以简化接口分配并使它们与实现分离。

将EJB注入Java Servlet

既然我们已经定义了EJB,就可以在Java EE Web模块中的servlet中使用它了。 假设在我们的应用程序中只有一个EJB实现了UniqueLocalBusinessInterface ,我们可以使用空的@EJB注释将其注入:

package es.reacts;import java.io.IOException;
import java.io.PrintWriter;import javax.ejb.EJB;import javax.servlet.*;
import javax.servlet.http.*;public class ServletTest1 extends HttpServlet {@EJBUniqueLocalBusinessInterface lc;public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {[...]lc.sayLocalHello();[...]}

首先要注意的是,由于仅bean接口就足以识别目标EJB,因此应用服务器将EJB注入了EJB。 在这种情况下,@EJB批注的beanInterface元件取它的默认值,因为在我们解释之前的帖子 UniqueLocalBusinessInterface:,那是注入字段的类型。 由于应用程序中只有一个EJB可以实现此业务接口,因此servlet的lc字段将注入对此类实例的引用。

值得指出的第二件事是,由于EJB是无状态的 ,因此我们正在将EJB安全地注入到servlet字段中。 由于servlet的默认情况下无状态的 ,你应该注射状态的资源转换成Servlet时域特性,否则你可能会碰到并发相关的问题。 如果需要在Servlet中使用有状态EJB,则应通过程序化JNDI查找来检索引用,因为这将确保每次查找操作都返回一个新实例。

让我们部署并运行我们的应用程序,我们将看到servlet注入了它的目标EJB,并且正确执行了对其业务接口的sayLocalHello()方法的方法调用。

如果我们想注入对远程接口的引用,则客户端代码不会受到影响。 如果尝试将UniqueLocalBusinessInterface@Local更改为@Remote ,那么您会看到该servlet没有任何变化,并且可以继续正常工作。

如果一个以上的EJB实现相同的接口会发生什么?

假设我们在此应用程序的EJB模块中添加了另一个EJB,它实现了与上一个相同的接口UniqueLocalBusinessInterface 。 在这种情况下,由于bean接口不再足以确定要注入的目标bean,因此将返回一个错误。 例如,在WebLogic Application Server中部署这样的应用程序会导致引发以下错误:

[08:46:25 PM] Caused by: weblogic.deployment.EnvironmentException: [J2EE:160199]Error resolving ejb-ref 'es.reacts.ServletTest1/lc1' from module 'WebTest0' of application 'EJBTestApp'. The ejb-ref does not have an ejb-link and the JNDI name of the target bean has not been specified. Attempts to automatically link the ejb-ref to its target bean failed because multiple EJBs in the application were found to implement the 'es.reacts.UniqueLocalBusinessInterface' interface. Please specify a qualified ejb-link for this ejb-ref to indicate which EJB is the target of this ejb-ref.

注入对特定EJB实例的引用

为了解决上一节中出现的问题,我们需要为应用程序服务器提供所需的信息,以标识目标EJB。 如前一篇文章所述 ,我们可以使用以下两种方法:

  • 我们可以使用@EJB批注的name元素(或部署描述符的相应<ejb-ref-name />元素)在应用程序的私有名称空间中声明EJB引用,然后使用EJB链接到目标bean。部署描述符。
  • 或者,我们使用@EJB批注的beanName元素(或部署描述符的相应<ejb-link />元素)直接在我们的代码中进行操作。

将EJB映射到私有命名空间

使用第一种方法,我们将在servlet中获得以下代码:

@EJB(name = "ejb/bean-name")
UniqueLocalBusinessInterface lc;

以及充当EJB客户端的Java EE Web模块的部署描述符(web.xml)中的以下元素:

<ejb-local-ref><ejb-ref-name>ejb/bean-name</ejb-ref-name><ejb-ref-type>Session</ejb-ref-type><local>es.reacts.UniqueLocalBusinessInterface</local><ejb-link>UniqueLocalSessionEJB</ejb-link>
</ejb-local-ref>

<ejb-link />元素包含我们在示例开头定义的带注释的Bean名称:

@Stateless(name = "UniqueLocalSessionEJB")

在EJB实现类中。

请注意,在此示例中,我们显式使用了@EJB name元素,但是我们可以使用其默认值来建立链接。 name元素的默认值为:

[合格的类名称] / [属性或字段名称]

在这种情况下,将是:

es.reacts.ServletTest1 / lc

使用默认的自动生成的名称以及使用<ejb-link />进行EJB链接的缺点是,每次重构代码时,都必须检查部署描述符。 尽管开发人员有时会另外考虑,但Java EE规范定义了一些其他角色,例如,攻击者和部署者。 在大型公司环境中,此类概要文件会覆盖开发人员的注释以“插入”应用程序使用的组件并不少见。 注释覆盖是标准部署描述符仍然存在的原因之一。 当引用是在应用程序内部或外部的远程组件时,尤其如此。 为此,我建议你不要依赖于自动生成的名称,并使用自定义的有据可查的名称代替。

将EJB链接到私有命名空间中的引用

第二种方法提供了使用@EJB批注的beanName元素将引用链接到其目标bean的直接方法。 Servlet代码将使用以下EJB参考:

@EJB(beanName = "UniqueLocalSessionEJB")
UniqueLocalBusinessInterface lc;

并且我们不需要部署描述符中的其他信息。

尽管此方法允许开发人员在不依赖部署描述符的情况下将引用链接到EJB,但是上一节末尾给出的建议仍然有效。 请记住,可以在部署时覆盖注释! 如果事先知道这样的引用可以覆盖,则不要将EJB链接到引用。 在这种情况下,最好为引用指定一个名称,如上一节所述。

参考: The Gray Blog上的JCG合作伙伴 Gray提供了基本的EJB参考,注入和查找 。

相关文章 :
  • EJB 3.0注入和查找简介
  • EJB程序化查找
  • 使用Oracle WebLogic对应用程序外部的EJB的引用
  • EJB 3.1全局JNDI访问
  • GWT EJB3 Maven JBoss 5.1集成教程
  • Java泛型快速教程
  • JVM如何处理锁

翻译自: https://www.javacodegeeks.com/2011/08/basic-ejb-references-injection-and.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/374785.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ViewPager使用笔记

1.ViewPager.setCurrentItem(position)&#xff0c;即使已设置动画&#xff0c;但是没有动画效果 原因&#xff1a;因为ViewPager滑动之前的时间间隔太短&#xff0c;可以通过反射&#xff0c;去修改ViewPager自动滑动时间&#xff0c;代码实现如下 1 public class ViewPagerSc…

IOS开发之Swift学习笔记

1.因为存储属性要求初始化&#xff0c;我们可以使用lazy修饰符来延迟初始化。转载于:https://www.cnblogs.com/luntai/p/5430223.html

力扣1两数之和

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…

C ++或Java,高频交易哪个更快?

总览 关于什么是高频交易的最佳解决方案&#xff0c;存在不同意见。 问题的一部分是高频交易的变化超出您的预期&#xff0c;另一部分是更快的含义。 我的看法 如果您有一个典型的Java程序员和一个典型的C 程序员&#xff0c;并且每个人都有几年编写典型的面向对象程序的经验…

iOS 8 Xcode6 设置Launch Image 启动图片

本人apem http://www.mamicode.com/info-detail-494411.html 如何设置App的启动图,也就是Launch Image? Step1 1.点击Image.xcassets 进入图片管理,然后右击,弹出"New Launch Image"2.如图,右侧的勾选可以让你选择是否要对ipad,横屏,竖屏,以及低版本的ios系统做支持…

代码分享h5-sessionStorage,提示app下载代码块

1.html <div class"down-app">    <span id"dowm-close">x</span>    <dl>      <dt>logo</dt>      <dd>        <h3>某某公司</h3>        <p>某某公…

Apache CXF负载平衡和故障转移

前一段时间&#xff0c;我们已经面临基于Apache CXF的负载平衡Web服务客户端的需求。 此外&#xff0c;当某些服务器关闭时&#xff0c;客户端应自动进行故障转移。 更糟糕的是&#xff0c;服务器目标地址列表要从外部服务获取并在运行时更新。 最终&#xff0c;我们最终获得了…

Java局部变量一定要赋初值

根据大佬文章https://blog.csdn.net/wjw521wjw521/article/details/79243596的理解而写的 1.类成员变量在 类加载 时会被系统赋初值&#xff0c;比如定义一个整型变量int num 系统默认num值为0 2.但是方法内的局部变量执行进栈操作&#xff0c;这个过程中系统不会赋初值&…

隐式的类类型转换

如果构造函数只接受一个实参&#xff0c;则它实际上定义了转换为此类类型的隐式转换机制。将这种构造函数称为转换构造函数。 #ifndef MAIN_H_INCLUDED#define MAIN_H_INCLUDED#include<iostream>usingnamespace std;classClassTest{public:ClassTest(){ cout <<&q…

负数的 %求余和取模

1.求余和取模是不同的 2.‘%’ 在C/C&#xff0c;Java等语言中意为 求余 &#xff0c;在python 中意为 取模 3.a%b c 求余: c的符号和a一致 取模&#xff1a;c的符号和b一致 比如&#xff0c;一个小李子&#xff1a; public class Solution{public static void main(String…

PAT-BASIC-1038-统计同成绩学生

本题要求读入N名学生的成绩&#xff0c;将获得某一给定分数的学生人数输出。 输入格式&#xff1a; 输入在第1行给出不超过105的正整数N&#xff0c;即学生总人数。随后1行给出N名学生的百分制整数成绩&#xff0c;中间以空格分隔。最后1行给出要查询的分数个数K&#xff08;不…

JavaScript事件处理的三种方式(转)

一、什么是JavaScript事件&#xff1f;事件(Event)是JavaScript应用跳动的心脏&#xff0c;也是把所有东西粘在一起的胶水&#xff0c;当我们与浏览器中Web页面进行某些类型的交互时&#xff0c;事件就发生了。 事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键…

Erlang与Java内存架构

我读了一篇关于Erlang VM的内存管理策略的非常非常有趣的文章。 它是Jesper Wilhelmsson撰写的论文 &#xff0c;我认为讨论Erlang的内存设置和Oracle的Java VM之间的差异可能会很好。 作为对从未听说过Erlang的人的真正的简短介绍; 它是一种功能语言&#xff0c;使用异步消息传…

Xuggler教程:转码和媒体修改

注意&#xff1a;这是我们的“ Xuggler开发教程 ”系列的一部分。 在之前的教程中&#xff0c;我对视频处理Xuggler进行了简短介绍 。 在这一部分中&#xff0c;我们将看到Xuggler和FFmpeg提供的一些更令人兴奋的功能&#xff0c;例如视频转码和媒体修改。 不要忘记Xuggler是一…

Web工程师必备的43款可视化工具

国外站点DATAVISUALIZATION.CH为大家总结出了当前热用的43款可视化工具&#xff0c;包括Arbor、Chroma.js、D3.js、Google Chart Tools等&#xff0c;绝对让你一饱眼福。 1.Arbor.js Arbor是一个免费的、可视化的图形库&#xff0c;基于矢量创建动态的连接图。它为图形组织和屏…

力扣7. 整数反转

方法一&#xff1a;官方给的&#xff0c;自己懂了后照着敲了一遍 class Solution {public int reverse(int x) {int rev 0;while (x ! 0) {//if判断条件过于复杂&#xff0c;我好不容易看懂了if (rev < Integer.MIN_VALUE / 10 || rev > Integer.MAX_VALUE / 10) {retu…

AndroidManifest.xml中的application中的name属性

被这个不起眼的属性折磨了一天&#xff0c;终于解决了。 由于项目需要&#xff0c;要合并两个android应用&#xff0c;于是拷代码&#xff0c;拷布局文件&#xff0c;拷values&#xff0c;所有的都搞定之后程序还是频频崩溃&#xff0c;一直没有找到原因&#xff0c;学android…

完美单身

我不时遇到一些Java程序员&#xff0c;他们不确定他们应该如何正确实现Singleton模式。 &#xff08;如果您不知道什么是Singleton&#xff0c;请尝试Wikipedia&#xff1a; Singleton模式 &#xff09;。 我并不是在谈论在线程环境中的正确实现。 但是&#xff0c;使用最常见的…

力扣移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 我写的代码思路是从开始元素找0&#xff0c;找到了就将这个0后面的元素向前移一位 class Solution {public void moveZeroes(int[] nums) {int n nums.length;…

Doclava:来自Google的自定义Javadoc Doclet

Doclava是Google的自定义Javadoc Doclet&#xff0c;由Google Guice使用&#xff08;请参阅稍冷的 Javadocs &#xff09;。 Doclava使用JSilver作为其模板引擎&#xff0c;这是Clearsilver的纯Java实现。 我个人喜欢联合文档的想法&#xff0c;它允许文档在打开的项目上相互链…