微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在单例中注入的 CDI 拦截器不被 Glassfish 5.1 容器调用

如何解决为什么在单例中注入的 CDI 拦截器不被 Glassfish 5.1 容器调用

在日志文件中记录方法进入和退出的CDI拦截器没有被容器为单例类调用

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD,TYPE})
public @interface Logit {
}

这里是拦截器:

@Interceptor
@Logit
public class RecordIntereceptor implements Serializable {
    private static final long serialVersionUID = -2230122751970857900L;
    public RecordIntereceptor() {
    }
    @AroundInvoke
    public Object logEntryExit(InvocationContext ctx)throws Exception{
        String methodName = ctx.getmethod().getName();
        String declaringClass= ctx.getmethod().getDeclaringClass().getCanonicalName();
        Logger logger = Logger.getLogger(declaringClass);
        logger.entering("List Service Intereceptor "+declaringClass,methodName);
        Object result = ctx.proceed();
        logger.exiting("List Service Intereceptor "+declaringClass,methodName);
        return result;
    }
    
}

这是一个使用拦截器的单例类:

@Logit
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DataLoaderSessionBean {
 @postconstruct
    public void createData() {
        removeStartupData();
        loadUsers();
        loadParts();
    }
...........
...........
}

最后是 beans.xml

<?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">
    <interceptors>
        <class>org.me.jsfproject.intereceptor.RecordIntereceptor</class>
    </interceptors>
</beans>

日志文件中没有方法DataLoaderSessionBean.createData()”的方法进入或退出日志。使用调试器,我单步执行代码并且容器没有调用拦截器。虽然拦截器对非单例类工作正常?知道为什么会这样。

更新 1

具有生命周期方法(即@postconstruct)的拦截器似乎有限制,它们必须是@Target({TYPE}) 所以我创建了一个额外的新拦截器接口和一个新的拦截器,仅用于单例类,如下所示:
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({TYPE})
public @interface LifeCycleLogger {
}

@Interceptor
@LifeCycleLogger

public class LifeCycleIntereceptor implements Serializable {
    private static final long serialVersionUID = -2230122753370857601L;
    public LifeCycleIntereceptor() {
    }
   
    @postconstruct
    public void logpostconstruct(InvocationContext ctx){
        String methodName = ctx.getmethod().getName();
        String declaringClass= ctx.getmethod().getDeclaringClass().getCanonicalName();
        Logger logger = Logger.getLogger(declaringClass);
        logger.entering("Life Cycle Intereceptor "+declaringClass,methodName);
        try {
            ctx.proceed();
        } catch (Exception e) {
            logger.log(Level.SEVERE,"LifeCycle Interceptor Post Construct caught an exception: {0}",e.getMessage());
        }
        
        logger.exiting("Life Cycle Intereceptor "+declaringClass,methodName);
    }
}

我改变了单例如下:

@LifeCycleLogger
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DataLoaderSessionBean{

................
    public DataLoaderSessionBean(){
        
    }

    @postconstruct
    public void createData() {
        ........
        
    }
............
}

但是,createData() 方法没有进入或退出日志吗?

谢谢

?

解决方法

由于 createData()DataLoaderSessionBean 的生命周期方法,它不会被 @AroundInvoke 注释捕获。

要在拦截器中声明捕获 @PostConstruct 生命周期调用的方法,您必须使用相同的注释对其进行注释:

@PostConstruct
public void logPostConstruct(InvocationContext ctx) throws Exception{
    String methodName = ctx.getMethod().getName();
    String declaringClass= ctx.getMethod().getDeclaringClass().getCanonicalName();
    Logger logger = Logger.getLogger(declaringClass);
    logger.entering("List Service Intereceptor "+declaringClass,methodName);
    ctx.proceed();
    logger.exiting("List Service Intereceptor "+declaringClass,methodName);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?