理解多CDI /焊接
我有一个包含在包含许多JAR(包含EJB,库,第三方库,...)和单个WAR(同样包含一些其他JAR)的EAR中的应用程序。 该应用程序部署在JEE7容器(Wildfly 8.0.0.Final)中,并使用CDI(Weld 2.1.2.Final与Wildfly一起提供)。
根据我的理解,Weld在应用程序范围内是活跃的,并且具有单一的应用程序范围的视图。 所以,我想在哪里使用CDI并不重要 - 它可以工作。
但是有一些迹象表明这是不正确的。 例如, BeanManager
的toString
方法在不同模块中显示不同的输出:
当在战争中打包的某个模块中使用BeanManager
,我将获得Weld BeanManager for 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中直接包含的库中: Weld BeanManager for test-ear-1.0-SNAPSHOT.ear/test-ejb3-dao-1.0-SNAPSHOT.jar/ [bean count=224]
。
所以这些BeanManagers
似乎是“负责”应用程序的不同部分。 这是真的?
这由理解EAR规范的应用程序服务器来处理。
维基百科:
大多数应用程序服务器将部署的EAR文件中的类作为Java类加载器的独立树进行加载,从而将应用程序与其他应用程序隔离,但在部署的模块之间共享类。 例如,已部署的WAR文件将能够创建JAR文件中定义的类的实例,该JAR文件也包含在包含EAR文件中,但不一定包含在其他EAR文件的JAR文件中。 这种行为的一个关键原因是允许完全分离使用静态单例的应用程序(例如Log4J),否则会在不同的应用程序之间混淆配置。 这也使不同版本的应用程序和库可以并排部署。
所以每个模块都有它自己的BeanManager
而应用服务器管理这些实例之间的依赖关系。