java around_java – @AroundInvoke拦截器在@WebService类上被调用两次

摘要

在@WebService类上调用@AroundInvoke拦截器两次,

如果截取的方法是通过端点作为SOAP Web服务从应用程序外部调用的.

如果从另一个bean内部调用相同的方法,它只被调用一次(正如我所料).

截获的方法本身始终只调用一次!

问题1:我可以只拦截一次拦截器吗?

问题2:如果我不能,是否有可转移的(服务器独立的)方式来决定我在哪个拦截器中,那么我可以忽略多余的拦截器?

问题3:这种行为是否常见(并在某些文档中定义和描述),

或者它是否依赖于我的特定环境(JBoss EAP 6.4.0)?

观察:

>这两个调用不在同一个拦截器链中.

>它与拦截器类的实例不同.

>两个调用的InvocationContext的实现类都不同.

>有趣的是,contextData(InvocationContext的用于沿拦截器链传递数据的字段)之一不是HashMap的实例,而是WrappedMessageContext,但它无论如何都不包装其他contextData.

最小的可重现代码

(我删除了包名.)

MyEndpoint界面

import javax.jws.WebService;

@WebService

public interface MyEndpoint {

public static final String SERVICE_NAME = "MyEndpointService";

public String getHello();

}

MyEndpointImpl类

import javax.interceptor.Interceptors;

import javax.jws.WebService;

@WebService(endpointInterface = "MyEndpoint", serviceName = MyEndpoint.SERVICE_NAME)

@Interceptors({TestInterceptor.class})

public class MyEndpointImpl implements MyEndpoint {

@Override

public String getHello() {

System.out.println("MyEndpointImpl.getHello() called");

return "Hello";

}

}

TestInterceptor类

import javax.interceptor.AroundInvoke;

import javax.interceptor.InvocationContext;

public class TestInterceptor {

@AroundInvoke

private Object countCalls(InvocationContext ic) throws Exception {

System.out.println("Interceptor called");

return ic.proceed();

}

}

产量

Interceptor called

Interceptor called

MyEndpointImpl.getHello() called

更多细节

为了获得更多运行时信息,我添加了更多日志记录

MyEndpointImpl类

import java.lang.reflect.Method;

import java.util.Map;

import javax.interceptor.AroundInvoke;

import javax.interceptor.InvocationContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class TestInterceptor {

private static Logger logger = LoggerFactory.getLogger(TestInterceptor.class);

private static int callCnt = 0;

@AroundInvoke

private Object countCalls(InvocationContext ic) throws Exception {

final String interceptorClass = this.toString();

final String invocationContextClass = ic.getClass().getName();

final Method method = ic.getMethod();

final String calledClass = method.getDeclaringClass().getName();

final String calledName = method.getName();

final String message = String.format(

"%n INTERCEPTOR: %s%n InvocationContext: %s%n %s # %s()",

interceptorClass, invocationContextClass, calledClass, calledName);

logger.info(message);

final int call = ++callCnt;

final Map contextData = ic.getContextData();

contextData.put("whoami", call);

logger.info("BEFORE PROCEED {}, {}", call, contextData);

final Object ret = ic.proceed();

logger.info("AFTER PROCEED {}, {}", call, contextData);

return ret;

}

}

产量

INTERCEPTOR: TestInterceptor@74c90b72

InvocationContext: org.jboss.invocation.InterceptorContext$Invocation

MyEndpointImpl # getHello()

BEFORE PROCEED 1, org.apache.cxf.jaxws.context.WrappedMessageContext@2cfccb1d

INTERCEPTOR: TestInterceptor@5226f6d8

InvocationContext: org.jboss.weld.interceptor.proxy.InterceptorInvocationContext

MyEndpointImpl # getHello()

BEFORE PROCEED 2, {whoami=2}

MyEndpointImpl.getHello() called

AFTER PROCEED 2, {whoami=2}

AFTER PROCEED 1, org.apache.cxf.jaxws.context.WrappedMessageContext@2cfccb1d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值