我有一个关于Java EE应用程序中EAR打包的优缺点的一般架构问题。 我在多个服务器环境中部署了Java EE业务应用程序。该应用程序包含以下主要模块:
在不考虑当前不同模块的更多细节的情况下,我将这些模块打包到EAR中,以部署在像GlassFish或WildFly这样的应用服务器上:
my.ear
/
+- META-INF/
| |- application.xml
|- my_ejb_module.jar
|- my_web_module.war
|- my_restservice.war
正如现在越来越多地讨论WebService和微服务架构,我想知道这种包装是否有点过时了?
当我开始项目多年时,这种打包似乎是最好的解决方案,因为包含业务逻辑的EJB模块在两个Web模块之间共享。
但是,当我今天看到自包含的微服务时,我想知道将应用程序拆分为两个可部署的Web模块是不是更好,其中每个模块都包含EJB模块:
web-ui.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_web_module.war
restservice.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_restservice.war
在此设置中,我可以在单独的计算机上部署REST API。所以看起来这种方法对EAR包装没有任何不利。
这是真的吗?我的问题是交易方向。如果两个Web模块在EAR包中共享相同的EJB模块,是否有任何优势?或者第二种方法是,两个Web模块包含相同的EJB模块,提供与事务处理和并发相同的功能吗?特别是当两个Web模块部署在同一个应用程序服务器上时。到目前为止,我能看到的唯一缺点是,我的EJB模块不能包含Java EE TimerServices或MessageDriven EJB,因为在war模块中部署时不支持这些类型的EJB。但在我的情况下,这是可以接受的。
答案 0 :(得分:0)
我试着自己回答我的问题: 在进行了一些测试部署后,我得出结论,在我的情况下,分裂是不可能的。原因是,我的ejb模块包含JPA实体bean。如果我部署两个包含相同实体bean的Web模块,这将破坏任何JPA缓存概念。只有当两个Web模块使用相同的REST服务访问JPA实体bean时才能实现分离。
所以我的示例部署看起来应该是这样的
web-ui.war
/
|- my_web_module.war
restservice.war
/
+- WEB-INF/lib
| |- my_ejb_module.jar
|- my_restservice.war
其中restservice.war是包含业务逻辑和数据库层(JPA实体bean)的主要模块,并且还发布了一个开放的REST API。 web-ui.war只包含一个Web应用程序,它通过来自restservice.war的REST API进行交互。 但是在两个Web模块中捆绑ejb模块是一种不好的做法。 EAR打包是有意义的,以便将所有模块捆绑在一起,并提供所有客户端模块(war模块)可以透明且以事务保存方式访问同一EJB模块的优点。
因此,包含JPA实体bean的EJB模块应该只部署一次,而不是捆绑到多个部署单元中。
答案 1 :(得分:0)
我在耳包装中看到的唯一缺点是有时耳朵是某种单块。简化您的架构 你可以摆脱耳包并分解那些整体,如果你使用完整的配置文件应用服务器,那么你可以单独部署ejb-jar作为jar文件,并从Web模块调用EJB。
您可以使用JNDI查找创建松散耦合的体系结构:
ExampleEJB exampleEJB;
...
private ExampleEJB getExampleEJB() {
if (this.exampleEJB == null) {
InitialContext ic = new InitialContext();
this.exampleEJB = (ExampleEJB)ic.lookup("ExampleEJB#com.example.ExampleEJB");
}
return this.exampleEJB
}
或通过注释使用CDI的紧耦合:
...
@EJB(mappedName="ExampleEJB")
ExampleEJB exampleEJB;
...
JNDI查找没有限制,您可以在任何类中使用它。在javaee 6中,注释仅适用于容器托管组件(使用@WebService,@ Stateless,@ Statefull等注释的类)。