Почему перехватчик 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}), поэтому я создал дополнительный новый интерфейс перехватчика и новый перехватчик только для класса 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);
}
}
Я изменил Singleton следующим образом:
@LifeCycleLogger
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class DataLoaderSessionBean{
................
public DataLoaderSessionBean(){
}
@PostConstruct
public void createData() {
........
}
............
}
Однако для метода createData() нет журналов входа или выхода?
Спасибо </p?
1 ответ
В качестве
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);
}