在日志文件中记录方法进出的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()
日志文件中没有方法的方法进入或退出日志。使用调试器,我单步执行代码并且容器没有调用拦截器。虽然拦截器对非单例类工作正常?知道为什么会这样吗?
具有生命周期方法的拦截器似乎存在限制(即@postConstruct
它们必须具有),@Target({TYPE})
因此我仅为 Singleton 类创建了一个额外的新拦截器接口和一个新拦截器,如下所示:
@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()
吗?