一直在努力工作,没有运气。
我正在从Spring 3.2.9升级到4.2.6。我的第一步是升级到cxf-core 3.1.6,我没有给应用程序带来任何问题。
升级所有spring依赖项时,我遇到拦截器设置问题。这是基础知识:
拦截
public class MyInterceptor extends AbstractPhaseInterceptor<Message>{
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
public MyInterceptor() {
super(Phase.PRE_INVOKE);
addAfter(HolderInInterceptor.class.getName());
}
@PostConstruct
public void display() {
logger.warn(this.getPhase());
}
@Override
public void handleMessage(Message message) throws Fault {
....
cxfContext.xml
<bean id="contentInInterceptor" class="com.MyInterceptor">
</bean>
<cxf:bus>
<cxf:inInterceptors>
<ref bean="contentInInterceptor"/>
</cxf:inInterceptors>
</cxf:bus>
以及它在web.xml中添加。在运行时,我看到显示拦截器的记录信息是在预调用阶段创建的(我添加了这个以验证我不会发疯)。但是在调用服务时,PhaseInterceptor链正在跳过拦截器而没有声明一个阶段:
日志:
2016-05-31 16:08:28,208 [localhost-startStop-1] []警告 c.MyInterceptor - 预先调用
2016-05-31 16:10:14,552 [http-bio-8080-exec-1] [] WARN o.a.c.p.PhaseInterceptorChain - 跳过拦截器 com.MyInterceptor $$ EnhancerBySpringCGLIB $$ 1afa70e1:阶段声明 不见了。
这是拦截jaxws服务器调用。再一次,我所做的一切都改变了,导致问题是更新到最新版本的Spring。看起来好像cxf正在使用一个从未从bean生成的独立拦截器。
修改
我相信我已经找到了这个问题,但我又不确定修复的位置。 Spring 4代理在创建代理时不会调用构造函数两次(即它使用构造函数创建原始bean,但CGLIB创建的bean代理不会调用构造函数)。这会导致拦截器的阶段为空。
我改变了我在课堂上的@PostContsruct以确认这一点:
@PostConstruct
public void display() {
logger.warn(this.getPhase());
MyInterceptor myInterceptor = (MyInterceptor) appContext.getBean("contentInInterceptor");
logger.warn("Bean phase is: " + myInterceptor.getPhase());
}
日志显示bean创建阶段与代理阶段:
2016-06-01 10:36:52,829 [localhost-startStop-1] [] WARN c.MyInterceptor - pre-invoke
2016-06-01 10:36:52,839 [localhost-startStop-1] [] WARN c.MyInterceptor - Bean阶段是:null
答案 0 :(得分:0)
你说拦截器正在拦截jaxws服务器调用。所以我的假设是,这是传出电话。
Phase.PRE_INVOKE
用于传入消息。使用Phase.PRE_STREAM
等其他阶段作为外发消息
有关阶段的文档,请参阅
答案 1 :(得分:0)
好吧,我现在想办法解决这个问题,但这并不是最好的实施方式。
基本上我最不得不做的是创建一个实现PhaseInterceptor的抽象类,并将所有这些实现的方法设置为抽象。
然后我的拦截器从该类延伸并在变量之前/之后有自己的阶段/ id /。当bean的直接类中没有变量时,看起来Spring的代理设置可能存在问题。至少这是我在这种情况下发现的。
同样,不确定它是否是最佳解决方案,但这会使拦截器再次发挥作用。