jakarta-ee - CDI:跨不同模块/bean文件使用拦截器

标签 jakarta-ee interceptor cdi ejb-3.1

我的 Java EE 6 应用程序包含一个 war 和一个打包在 ear 文件中的 ejb 模块。我将 CDI 用于 DI(即我在两个模块中都有一个 beans.xml 文件)。我也想使用在war模块的ejb模块中定义的日志拦截器。我在 ejb 的 beans.xml 中启用了拦截器:

<beans>
    <interceptors>
        <class>com.test.interceptor.LoggingInterceptor</class>
    </interceptors>
</beans>

这仅适用于在 中使用拦截器注释的类。 ejb模块 . war 模块中的类不会被拦截(尽管它们也被拦截器注解)。我认为解决方案是在 war 的拦截器中启用拦截器(如上)。但是无法使用以下消息部署应用程序:

严重:加载应用程序时出现异常:WELD-001417 启用的拦截器类 com.test.interceptor.LoggingInterceptor 既没有注释 @Interceptor 也没有通过可移植扩展注册

我的 LoggingInterceptor 看起来像这样:
@Log
@Interceptor
public class LoggingInterceptor {
    private static final Logger logger =  Logger.getLogger(LoggingInterceptor.class.getName());

    static {
        logger.setLevel(Level.ALL);
    }

    @AroundInvoke
    public Object logMethod(InvocationContext ctx) throws Exception {
        logger.log(Level.FINE, "ENTRY {0} {1}",
                new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() });
        long startTime = System.nanoTime();
        try {
            return ctx.proceed();
        } finally {
            long diffTime = System.nanoTime() - startTime;
            logger.log(Level.FINE, "RETURN {0} {1}",
                new Object[]{ ctx.getTarget().getClass().getName(), ctx.getMethod().getName() });
            logger.log(Level.FINE, "{0} took {1} ms", new Object[]{ ctx.getMethod(),
                    TimeUnit.MILLISECONDS.convert(diffTime, TimeUnit.NANOSECONDS)});
        }
    }

}

和拦截器绑定(bind):
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Log {}

如何将拦截器用于两个模块?

最佳答案

J2EE 7 规范说(reference):

The interceptors that you specify in the beans.xml file apply only to classes in the same archive. Use the @Priority annotation to specify interceptors globally for an application that consists of multiple modules



该解决方案具有独立于供应商的优势。

一个例子:
@Logged
@Interceptor
@Priority(Interceptor.Priority.APPLICATION)
public class LoggedInterceptor implements Serializable { ... }

关于jakarta-ee - CDI:跨不同模块/bean文件使用拦截器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4051069/

相关文章:

java - WebSphere v8.5 支持阿拉伯编码

java - request.getParameter() 在 servlet 中返回 null,除了一个参数

grails - 在 Grails/Groovy 中拦截或重命名方法调用

java - 如何使用 AS6 在 JMX 中使用 CDI 获取 'JBoss service'?

jakarta-ee - 如何在 Java EE 中使用 CDI 编写 main()?

java - 如何基于日期查询数据库,但您的数据库将日期存储为日期 + 时间。

Hibernate 拦截器获取与加载

java - 从 cxf 消息中获取 Http 请求正文

java - 通过远程接口(interface)将 EJB 注入(inject) servlet

java - 测试驱动开发问题