本地&远程访问一个EJB | 从开发角度看应用架构4
source link: http://www.10tiao.com/html/360/201806/2663487974/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一、前言
本文仅代表作者的个人观点;
本文的内容仅限于技术探讨,不能作为指导生产环境的素材;
本文素材是红帽公司产品技术和手册;
本文分为系列文章,将会有多篇,初步预计将会有9篇。
二、对EJB的访问方式
EJB是一个包含在应用程序服务器上运行的业务逻辑的可移植组件。 如果客户端和EJB是同一应用程序的一部分,则客户端可以在本地访问EJB,如果EJB在远程运行,则客户端可以通过远程接口访问EJB。
如果客户端和EJB是本地的,也就是说,它们在相同的JVM进程中运行,则客户端可以调用EJB中的所有公共方法。 在EJB远程的情况下,必须提供一个远程接口,它是一个公开EJB业务方法的简单Java接口。 EJB类实现远程接口中的方法,其实现细节对客户端是隐藏的。
使用@EJB注释访问本地EJB
假设已经定义了如下的EJB:
@Stateless
public class TodoBean {
public void addTodo(TodoItem item) {
...
}
public void findTodo(int id) {
...
}
...
}
...
}
客户可以通过使用@EJB注释将EJB直接注入到代码中来调用EJB上的方法:
public class TodoClient { @EJB
TodoBean todo;
TodoItem item = new TodoItem();
item.setDescription("Buy milk");
item.setStatus("PENDING");
//invoke EJB methods
todo.addTodo(item);
...
}
访问远程EJB
在客户机在Java EE应用程序服务器的上下文之外运行的情况下,或者在应用程序服务器上运行的Java EE组件需要访问部署在远程应用程序服务器上的另一个EJB的情况下,可以使用JNDI来查找EJB。
为了确保远程客户端可以使用EJB,必须声明一个列出EJB业务方法的接口,并让EJB实现并覆盖这些方法。 例如,假设希望提供执行各种数学操作的EJB,请声明一个接口并列出如下所示的方法:
package com.redhat.training.ejb;public interface Calculator {
public int add(int a, int b);
public int multiply(int a, int b);
...
}
我们现在必须在EJB中提供这些方法的具体实现,并通过使用@Remote注释指出Calculator是EJB的远程接口:
package com.redhat.training.ejb;@Stateless@Remote(Calculator.class)
public class CalculatorBean implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int multiply(int a, int b) {
return a * b;
}
...
}
...
}
我们的EJB现在可以打包并部署在应用服务器上,并可以为远程客户端提供服务。
三、使用JNDI查找远程EJB
Java EE标准为客户端指定了标准的JNDI查找方案来查找EJB。 示例如下:
/<application-name>/<module-name>/<bean-name>!<fully-qualified-interface-name>
application-name:应用程序名称是部署EJB的EAR的名称(没有.ear扩展名)。 如果EJB JAR没有在EAR中部署,那么这是空白的。 应用程序名称也可以在EAR的application.xml部署描述符中指定。
module-name:默认情况下,模块名称是EJB JAR文件的名称(不带.jar后缀)。 模块名称可以在ejb-jar.xml部署描述符中重写。
bean-name:要调用的EJB的名称(实现类)。
fully-qualified-interface-name:远程接口的完全限定类名。 包括完整的软件包名称。
考虑到上面的代码清单,假设EJB打包在名为calculator-ejb.jar的文件中,该文件被进一步打包到名为myapp.ear的EAR文件中。 客户端可以使用以下查找字符串查找EJB:
myapp/calculator-ejb/CalculatorBean!com.redhat.training.ejb.Calculator
在部署EJB时,应用程序服务器会在服务器日志中列出EJB的不同JNDI绑定。 下面的清单显示了如果将EJB打包并部署为JAR文件,而不是EAR文件,则显示JNDI条目:
INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-2) WFLYEJB0473: JNDI bindings for session bean named 'CalculatorBean' in deployment unit 'deployment "calculator-ejb.jar"' are as follows:java:global/calculator-ejb/CalculatorBean!com.redhat.training.ejb.Calculator
java:app/calculator-ejb/CalculatorBean!com.redhat.training.ejb.Calculator
java:module/CalculatorBean!com.redhat.training.ejb.Calculator
java:global/calculator-ejb/CalculatorBean
java:app/calculator-ejb/CalculatorBean
java:module/CalculatorBean
使用JNDI命名机制查找远程EJB的示例JNDI客户机程序如下所示:
package com.redhat.training.client;
public class CalculatorClient {
public static void main(String[] args) throws Exception { String JNDI_URL= "myapp/calculator-ejb/CalculatorBean!com.redhat.training.ejb.Calculator";
try {
Context ic = new InitialContext(); Calculator calc = (Calculator) ic.lookup(JNDI_URL);
System.out.println("Response from server = " + calc.add(1,2);
...
}
catch (Exception e) {
// handle the exception
}
}
...
}
我们还需要在客户端程序的类路径中提供一个名为jndi.properties的文件,其中包含运行EJB的远程应用程序服务器的主机名,IP地址,端口和安全详细信息(如果安全用于远程访问)。
java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory
java.naming.provider.url=http-remoting://10.2.0.15:8080
jboss.naming.client.ejb.context=true
JNDI API的InitialContext是一个标准的Java EE通用构造,用于查找部署在应用程序服务器上的组件。 它使用一组属性在类路径中查找jndi.properties。 某些属性对所有应用程序服务器都是通用的,有些属性是针对每个应用程序服务器的。
四、实验展现
实验由两个Maven子项目组成,它们位于hello-remote目录下的主项目文件夹下,其中包含hello-remote-ejb和hello-remote-client。
hello-remote-ejb项目在JBoss EAP中安装可远程访问的EJB,以便通过JNDI查找可用于外部客户端。 hello-remote-client项目是远程访问(从另一个JVM)EJB的Java SE应用程序。
首先,在JBDS中import已经存在的maven项目:
接下来,再import client:
查看hello-remote-ejb的pom.xml:
在源码的如下部分, 使用maven-ejb-plugin为ejb打包:
package已被声明为ejb,这告诉Maven如何打包最终的可部署artifact:
查看业务接口:HelloRemote.java
文件:
这是一个简单的Java接口,它带有一个公共方法sayHello(一个class),它接受一个字符串名称参数并返回一个字符串。 在使用EJB时,通常使用接口来定义可用的方法,而不考虑实现。
查看最终执行任务的类的源码:HelloBean.java文件。
注意到这个EJB类实现了HelloRemote接口的sayHello方法,并且注意到标记这个类为无状态EJB的@Stateless注解。
接下来,启动EAP:
接下来,通过运行以下命令来构建和部署EJB到JBoss EAP:
查看EAP日志,hello-ejb-remote.jar已经被部署到EAP中:
JBoss EAP要求将EJB绑定在java:jboss / exported / *名称空间下,以允许外部客户端查找和调用EJB。
注意到没有“导出的”JNDI绑定。 您需要为EJB提供一个远程接口,以便将EJB绑定在该名称空间下。
编辑EJB项目的实现类HelloBean.java以启用远程JNDI查找并重新部署应用程序。
编辑实现类HelloBean.java以启用远程JNDI查找。 将@Remote注释添加到您的实现类并保存该文件,在源码中增加以下两行:
重新编译和部署hello-ejb-remote:
再次观察JNDI绑定。 这次我们可以在JBDS Console选项卡中看到导出的JNDI绑定:
使用Maven将hello-remote-ejb构件安装到本地存储库中,以便在编译期间可供客户端项目使用:
接下来,查看hello-client项目的源代码,并更新它以使用JNDI查找HelloBean。
在JBDS左窗格的Project Explorer选项卡中展开hello-client项目,然后双击pom.xml文件。
单击pom.xml选项卡查看pom.xml,我们可以看到对hello-remote-ejb的依赖(需要远程调用它)依赖关系的类型是ejb-client。 这告诉Maven这个工件是用于代码编译的hello-remote-ejb工件中定义的EJB的客户端。
查看HelloClient.java源码,将下面突出的部分修改:
修改成如下样子:
更新jndi.properties文件(src/main/resources)以使用http-remoting来访问在本地JBoss EAP服务器上运行的EJB。
将java.naming.provider.url属性设置为值http-remoting://127.0.0.1:8080,如以下图例所示:
修改成:
接下来,编译并运行客户端:
最后一行的reponse说明客户端对ejb调用成功!
魏新宇
"大魏分享"运营者、红帽资深解决方案架构师
专注开源云计算、容器及自动化运维在金融行业的推广
拥有MBA、ITIL V3、Cobit5、C-STAR、TOGAF9.1(鉴定级)等管理认证。
拥有红帽RHCE/RHCA、VMware VCP-DCV、VCP-DT、VCP-Network、VCP-Cloud、AIX、HPUX等技术认证。
Recommend
-
1
我是为初级到中级的区块链爱好者写的——即具备在以太坊或其他主链上进行交易的经验,但对 L2 及其进展仍不太了解的人群。 原文:Layer 2 Playgrounds内容概要为什么要从 L1 到 L2?
-
2
Skaffold-简化本地开发kubernetes应用的神器-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生 在我们开发kubernetes应用的过程中,一般情况下是我们在本地开发调试测试完成以后,再通过CI/CD的方式部署到
-
32
最近发现家里宽带支持IPv6了,这里分享三个利用IPv6访问本地地址(内网地址)的方法。 通常来说,我们用localhost来代表本地地址 127.0.0.1 。其实在IPv6中有他自己的表示方法 ip6-localhost :
-
12
使用ngrok让你的本地Flask程序外网可访问 发表回复 注:本文隶属于《Flask Web开发实战》番...
-
4
AWS 最近宣布,用于 Amazon S3 的 PrivateLink 现在全面可用。有了 PrivateLink,客户可以安全地将 Amazon S3 连接到本地资源。 在去年的 AWS re:Invent 大会...
-
4
使用 inlets 和 kubernetes 访问本地服务-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生 A personal space for everyone 我们经常有在外网访问我们本地服务的需求,特别是在开发调试阶段,比如做微信...
-
4
在 《一篇带你用 VuePress + Github Pages 搭建博客》中,我们使用 VuePress 搭建了一个博客,最...
-
3
别人是无法通过一个链接访问到你家里的电脑的某个文件夹里面的文件的,因为你家里的电脑属于内网,而能通过一个链接去访问的属于公网,所以这就需要使用【内网穿透】这一个技术概念去实现远程访问家里电脑。frp是什么frp是一个专注于内网穿透的...
-
2
V2EX › 问与答 PWA 现在可以访问本地文件系统了,但好像每次访问都得用户授权,好像没法做到像客户端程序一样无感知地访问本地文...
-
2
防止第三方程序访问浏览器本地敏感数据 - V2EX V2EX = way to explore V2EX 是一个关于分享和探索的地方 Sponsored by
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK