6

我今天遇到了这种困惑。引用 Weld 的文档(在第 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 堆栈中项目唯一需要的东西。

更新

今天折腾了拦截器,发现如果用 old@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。

4

2 回答 2

9

在他的编辑中确认 JBT 的发现。根据 JEE6 规范的 Weld 1.0 实施的 JSR-299 的 CDI 规范 1.0。请参考我引用的这个指针

默认情况下,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;
    }
}

第三步可以使用以下任一方法实现

方法 1,一个空 beans.xml 将完成这项工作

@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............");
    }
}

方法2,需要beans.xml如下

<?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............");
    }
}
于 2013-12-01T02:25:30.670 回答
1

1.1默认情况下,拦截器和装饰器从版本中启用。查看新 CDI 规范的亮点

于 2013-10-15T07:11:26.513 回答