Kri*_*nya 6 java java-ee interceptor java-ee-6 websphere-8
我创建了一个自定义注释,如下所示
@InterceptorBinding
@Retention(RUNTIME)
@Target(TYPE, METHOD)
public @interface Traceable {}
Run Code Online (Sandbox Code Playgroud)
我写了一个拦截器,如下所示
@Traceable
@Interceptor
public class EnterExitLogger {
@AroundInvoke
public Object aroundInvoke(InvocatiobContext c) {}
}
Run Code Online (Sandbox Code Playgroud)
拦截器和注释位于名为common-utils的模块中.
我在类级别用@Traceable注释了我的目标类,如下所示
@Traceable
public class CDIManagedBean {
}
Run Code Online (Sandbox Code Playgroud)
我在beans.xml文件中声明了拦截器条目,如下所示
<interceptors>
<class>my.package.EnterExitLogger</class>
</interceptors>
Run Code Online (Sandbox Code Playgroud)
目标类位于单独的模块中.beans.xml位于目标类模块的META-INF目录中.
目标类的方法是从rest类调用的.当我调用方法时,不会调用拦截器的AroundInvoke方法.
我阅读了文档,并了解拦截器应该包含一个公共的无参数构造函数.我加了.但仍然没有调用拦截器.
我在阅读完文档后在自定义注释中添加了@Inherited.但仍然没有调用拦截器.
从文档中我注意到拦截器实现了Serializable接口.虽然没有提到我也实现了Serializable.仍然没有奏效.
然后我从拦截器,beans.xml文件和目标类中删除了自定义注释.我还从拦截器中删除了public no参数构造函数并删除了Serializable.
然后我用目标类注释@Interceptors(EnterExitLogger.class)并调用了流程.我的拦截器被调用了.
任何人都可以告诉我如何处理InterceptorBinding?
PS
我正在WAS 8.5服务器上部署我的耳朵.
在Java EE的教程提供了一个很好的解释和有关拦截器的几个例子:
创建一个拦截器绑定注释,必须使用@Inherited和注释@InterceptorBinding:
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logged { }
Run Code Online (Sandbox Code Playgroud)
创建使用上面创建的拦截器绑定注释以及注释注释的incerceptor类@Interceptor.
每个@AroundInvoke方法都接受一个InvocationContext参数,返回一个Object并抛出一个Exception.该@AroundInvoke方法必须调用该InvocationContext#proceed()方法,这会导致调用目标类方法:
@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {
public LoggedInterceptor() {
}
@AroundInvoke
public Object logMethodEntry(InvocationContext invocationContext) throws Exception {
System.out.println("Entering method: "
+ invocationContext.getMethod().getName() + " in class "
+ invocationContext.getMethod().getDeclaringClass().getName());
return invocationContext.proceed();
}
}
Run Code Online (Sandbox Code Playgroud)
一旦定义了拦截器和绑定类型,就可以使用绑定类型注释bean和单个方法,以指定在bean的所有方法或特定方法上调用拦截器.
例如,PaymentHandlerbean被注释@Logged,这意味着任何对其业务方法的调用都将导致@AroundInvoke调用拦截器的方法:
@Logged
@SessionScoped
public class PaymentHandler implements Serializable {...}
Run Code Online (Sandbox Code Playgroud)
但是,您只能通过注释所需的方法来拦截bean的一组方法:
@Logged
public String pay() {...}
@Logged
public void reset() {...}
Run Code Online (Sandbox Code Playgroud)
为了在CDI应用程序中调用拦截器,必须在beans.xml文件中指定:
<interceptors>
<class>your.package.LoggedInterceptor</class>
</interceptors>
Run Code Online (Sandbox Code Playgroud)
如果应用程序使用多个拦截器,则会按beans.xml文件中指定的顺序调用拦截器.