Java 理解CDI/Weld在多模块应用中的作用

Java 理解CDI/Weld在多模块应用中的作用,java,cdi,weld,Java,Cdi,Weld,我有一个应用程序,它打包在一个EAR中,包含许多JAR(带有EJB、库、第三方库等)和一个WAR(同样包含一些其他JAR)。该应用程序部署在JEE7容器(Wildfly 8.0.0.Final)中,并使用CDI(Wildfly附带的Weld 2.1.2.Final) 据我所知,Weld在应用范围内是活跃的,并且具有单一的应用范围视图。所以我想在哪里使用CDI并不重要——它可以工作 但有一些迹象表明,这是不正确的。例如,BeanManager的toString-方法在不同的模块中显示不同的输出:

我有一个应用程序,它打包在一个EAR中,包含许多JAR(带有EJB、库、第三方库等)和一个WAR(同样包含一些其他JAR)。该应用程序部署在JEE7容器(Wildfly 8.0.0.Final)中,并使用CDI(Wildfly附带的Weld 2.1.2.Final)

据我所知,Weld在应用范围内是活跃的,并且具有单一的应用范围视图。所以我想在哪里使用CDI并不重要——它可以工作

但有一些迹象表明,这是不正确的。例如,
BeanManager
toString
-方法在不同的模块中显示不同的输出:

在war I get中打包的某个模块中使用
BeanManager
test-ear-1.0-SNAPSHOT.ear/test-webui-frontend-1.0-SNAPSHOT.war/WEB-INF/lib/test-webui-backend-1.0-SNAPSHOT.jar[bean count=76]

如果在EAR中直接包含的库中使用:
test-ear-1.0-SNAPSHOT.ear/test-ejb3-dao-1.0-SNAPSHOT.jar的焊接BeanManager/[bean count=224]


因此,这些
BeanManager
似乎“负责”应用程序的不同部分。这是真的吗?

这是由理解EAR规范的应用程序服务器处理的

来自维基百科:

大多数应用服务器从部署的EAR文件中加载类作为 Java类加载器的隔离树,将应用程序与 其他应用程序,但在部署的模块之间共享类。对于 例如,部署的WAR文件将能够创建 在JAR文件中定义的类,该JAR文件也包含在包含 EAR文件,但不一定是其他EAR文件中JAR文件中的文件。 这种行为的一个关键原因是允许完全分离 在使用静态单例(例如Log4J)的应用程序之间 否则会将配置与单独的 应用。这还支持不同版本的应用程序和应用程序 要并排部署的库


因此,每个模块都有自己的
BeanManager
,而应用程序服务器管理这些实例之间的依赖关系。

你说得对。它看起来像是
toString
-输出的
for…
是在当前上下文中处于活动状态的类加载器。但这是否意味着应用程序服务器持有许多不同的“CDI应用程序”(或
BeanManager
),它们完全独立地处理其CDI上下文(如应用程序范围)?不,应用程序范围存在于应用程序中,即EAR应用程序。但是每个模块都有自己的BeanManager,而应用服务器在管理这些实例之间的依赖关系。那么,不同的BeanManager是否有实际影响呢?如果否:为什么值得在
toString
输出中提及modulename/classloader?否,我猜这是因为您需要从归档文件中单独访问
BeanManager
(以及它的类加载器)。同样,Weld不知道您的应用程序是否是EAR,但应用程序服务器知道应用程序中有几个
BeanManager
,并将它们绑定在一起。老实说,我不知道为什么在
toString()
输出中提到类加载器,可能是出于调试目的。