为何@EnableWs会移除Spring Bean的AOP代理?
为什么@EnableWs会移除Spring Bean的AOP代理?
这个问题我之前也碰到过,其实根源在于@EnableWs背后的Spring WS配置逻辑和Spring AOP的代理机制存在冲突,具体原因可以拆解成这几点:
Spring WS的Bean初始化绕过了AOP代理
@EnableWs会自动引入WsConfigurationSupport类,这个类在注册核心的MessageDispatcherServlet时,会直接从ApplicationContext中获取原始Bean实例,而没有通过Spring的代理工厂获取代理后的对象。比如它可能用了context.getBean(SomeClass.class)这种按类型获取Bean的方式,这种方式默认会返回原始对象(如果是JDK动态代理的话,代理类和原始类不是同一个类型),直接把AOP代理给“剥离”了。代理类型不兼容
如果你的AOP用的是JDK动态代理(默认接口代理),而Spring WS在处理Bean时只认原始类类型,就会跳过代理实例,直接拿到目标对象。这时候AOP的切面逻辑自然就不会生效了。
解决办法
这里给你几个实用的解决方向:
- 强制使用CGLIB代理
在你的配置类上加上@EnableAspectJAutoProxy(proxyTargetClass = true),这样Spring会用CGLIB生成目标类的子类作为代理,即使按类型获取Bean,拿到的也是代理后的子类实例,AOP逻辑就能正常生效了。示例代码:
@Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @EnableWs public class AppConfig { // 你的其他Bean配置 }
- 手动注册Spring WS的Servlet
放弃@EnableWs的自动配置,手动注册MessageDispatcherServlet,确保获取Bean时用名称而不是类型,这样Spring会返回代理后的实例。示例:
@Configuration @EnableAspectJAutoProxy public class CustomWsConfig { @Bean public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(ApplicationContext context) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(context); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean<>(servlet, "/ws/*"); } // 手动配置WS的其他组件,比如Wsdl11Definition @Bean(name = "exampleWsdl") public Wsdl11Definition defaultWsdl11Definition() { SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition(); wsdl11Definition.setWsdl(new ClassPathResource("example.wsdl")); return wsdl11Definition; } }
- 检查切面的配置正确性
确保你的PersistentAspect类加上了@Aspect和@Component注解,并且Spring的组件扫描路径包含这个类所在的包,避免切面本身就没被Spring识别到。
内容的提问来源于stack exchange,提问作者hudi
相关产品推荐
相关产品推荐

