【发布时间】:2019-06-04 23:52:38
【问题描述】:
在这方面工作了一段时间,但没有任何运气。
我正在从 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] [] 警告 o.a.c.p.PhaseInterceptorChain - 跳过拦截器 com.MyInterceptor$$EnhancerBySpringCGLIB$$1afa70e1:阶段声明 不见了。
这是拦截 jaxws 服务器调用。同样,我所做的所有导致问题的更改都是更新到最新版本的 Spring。看起来好像 cxf 正在使用一个从未从 bean 生成的单独拦截器。
编辑
我相信我已经找到了问题所在,但我再次不确定要解决的问题。 Spring 4 代理在创建代理时不会调用构造函数两次(即它使用构造函数创建原始 bean,但 bean 的 CGLIB 创建的代理不调用构造函数)。这会导致拦截器的相位为空。
我在课堂上更改了@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 - 预调用
2016-06-01 10:36:52,839 [localhost-startStop-1] [] WARN c.MyInterceptor - Bean 阶段为:null
【问题讨论】:
-
感谢这篇文章,因为我今天遇到了同样的问题。 8小时后,实现了自己的IN拦截器,没有扩展AbstractPhaseInterceptor,拦截器终于又被调用了。对于其他人来说,这个问题是在从 spring 3.2.x 迁移到 5.1.x 之后出现的 PS:我为这条消息道歉(而不是评论),但我还没有所需的声誉。