Java EE7多模块Maven项目CDI拦截器跨模块生效配置问题
Java EE 7 跨模块CDI拦截器生效配置方案
核心原因说明
Java EE 7 环境下EAR部署的各模块(EJB、WAR)属于独立的CDI上下文,默认仅扫描自身和EAR公共lib目录下的合法Bean归档。你遇到的配置不生效问题基本是Bean归档规则、打包位置、拦截器注册这几个环节配置不到位导致的。
分步配置方案
1. common-jar模块配置
- 将拦截器实现类、自定义拦截器绑定注解都放在common-jar模块下,拦截器类需要添加
@Interceptor注解和自定义绑定注解,同时补充@Dependent作用域注解保证CDI可识别。 - 在common-jar的
META-INF目录下添加beans.xml,按CDI 1.1规范配置,示例如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="annotated"> </beans>
如果你没有给拦截器加作用域注解,需要将
bean-discovery-mode改为all,也可以直接在该文件的<interceptors>标签下全局注册拦截器,适用于不需要自定义绑定注解的全局拦截场景。
2. 打包规则配置
- 调整Maven打包逻辑,保证common-jar最终被打包到EAR根目录的
lib文件夹下,而不是仅存放在WAR模块的WEB-INF/lib目录:- 在ear模块的pom.xml中引入common-jar的依赖,scope设为
compile - 配置
maven-ear-plugin的<defaultLibBundleDir>lib</defaultLibBundleDir>,自动将公共依赖打入EAR的lib目录 - ejb-jar和war模块的pom.xml中引入common-jar依赖时,scope设为
provided,避免重复打包
- 在ear模块的pom.xml中引入common-jar的依赖,scope设为
3. 子模块CDI开启配置
- 在ejb-jar模块的
META-INF目录下添加beans.xml,bean-discovery-mode和common-jar保持一致即可,无需重复注册拦截器 - 在war模块的
WEB-INF目录下添加beans.xml,同样配置正确的bean-discovery-mode开启CDI扫描
4. 特殊应用服务器适配(可选)
如果使用WebLogic、JBoss EAP/Wildfly等有自定义类加载规则的应用服务器,可补充对应配置避免类加载冲突:
- JBoss系:在ear的
META-INF下添加jboss-deployment-structure.xml,配置导出common-jar的包给所有子模块 - WebLogic:在ear的
META-INF下添加weblogic-application.xml,通过<prefer-application-packages>标签指定拦截器所在包优先从EAR公共lib加载
内容的提问来源于stack exchange,提问作者Asier Naiz
相关产品推荐
相关产品推荐

