我今天遇到了这种混乱。 Quote from Weld's documentation (right under Section 9.3),
默认情况下,禁用所有拦截器。我们需要启用我们的 拦截器。我们可以使用bean的beans.xml描述符来完成它 存档。但是,此激活仅适用于其中的bean 档案
但是,在我目前正在进行的项目中,我有一个用于分析方法的拦截器。我的META-INF/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"
version="1.1" bean-discovery-mode="all">
</beans>
然而,我仍然从该剖析拦截器得到预期的日志。那么,正如标题所示,拦截器默认是否真的被禁用了?
顺便说一句,我在项目中使用weld-se
来获取CDI功能,因为CDI是Java EE堆栈中项目所需要的唯一东西。
今天搞乱了拦截器之后,我发现如果使用旧的@Interceptors
来表示拦截实现类,则不需要在beans.xml
中指定任何内容。但是,如果使用拦截器绑定,即使用@Interceptor
注释来指示拦截器类,则必须通过将拦截器类添加到beans.xml
来启用拦截。根据我的经验,CDI 1.1仍然如此,正如上面beans.xml
中的版本所示。顺便说一句,我在这种情况下使用org.jboss.weld.se:weld-se:2.0.4.Final
进行CDI实现,我认为它实现了CDI 1.1。
答案 0 :(得分:8)
在他的编辑中确认JBT的发现。根据Weld 1.0为JEE6规范实施的JSR-299的CDI规范1.0。请参考我引用的this pointer:
默认情况下,bean归档文件没有通过拦截器绑定绑定的已启用拦截器。必须通过在
<class>
的子<interceptors>
元素中列出完全限定的类名来显式启用拦截器。 如下面的方法2
举个例子:
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Loggable {
}
@Interceptor
@Loggable
public class LoggingInterceptor {
@AroundInvoke
public Object logMethodEntry(InvocationContext ctx) throws Exception{
System.out.println("In LoggingInterceptor..................... before method call");
Object returnMe = ctx.proceed();
System.out.println("In LoggingInterceptor..................... after method call");
return returnMe;
}
}
@Stateless
@Interceptors(LoggingInterceptor.class) //class interception
public class Displayer implements DisplayerLocal {
@Override
//@Interceptors(LoggingInterceptor.class) //method interception
public void displayHi() {
System.out.println(".....Hi there............");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.companyname.LoggingInterceptor</class>
</interceptors>
</beans>
然后截获的课程:
@Stateless
@Loggable //class interception
public class Displayer implements DisplayerLocal {
@Override
//@Loggable //method interception
public void displayHi() {
System.out.println(".....Hi there............");
}
}
答案 1 :(得分:1)
默认情况下,1.1
版本启用了拦截器和装饰器。请参阅新CDI规范的highlights。