Spring AOP在Spring SOAP Web Service中失效问题求助
问题解答:Spring AOP切面不触发Endpoint的protected方法
你的观察完全正确——Spring AOP默认只对公共(public)方法生效,这就是为什么把invokeInternal改成public后切面能正常工作的核心原因。下面具体解释背后的逻辑和可选方案:
1. Spring AOP的代理机制限制
Spring AOP主要依赖两种代理实现方式,两者都对非公共方法有拦截限制:
- JDK动态代理:基于接口生成代理类,只能代理接口中定义的公共方法,完全无法处理protected、private这类非公共方法。
- CGLIB代理:通过子类继承目标类生成代理,理论上可以拦截非公共方法,但Spring默认配置会主动跳过这类方法的拦截。这是Spring的设计选择,遵循Java封装原则——AOP通常用于对外暴露的公共方法,而非内部私有/保护方法。
你的MyEndPoint继承了AbstractJDomPayloadEndpoint,invokeInternal是protected方法,刚好落在Spring AOP的默认拦截范围之外,所以切面不会触发。
2. 针对你的场景的解决方案
方案一:保持public修饰符(推荐)
改成public后切面正常工作,这是最简单的解决方案。Spring WS框架本身是通过反射调用invokeInternal方法的,调整访问修饰符不会破坏原有功能,完全可以放心使用。
方案二:使用AspectJ织入(进阶)
如果一定要保留protected修饰符,可以放弃Spring AOP的动态代理,改用AspectJ编译时织入(CTW)或加载时织入(LTW)。AspectJ是原生AOP框架,不受Spring代理机制的限制,可以拦截任何访问修饰符的方法。不过这种方式配置更复杂:
- 编译时织入需要修改Maven/Gradle的编译插件,在编译阶段把切面代码织入目标类。
- 加载时织入需要添加Java Agent,在类加载时动态完成切面织入。
补充:关于你的切点表达式
你的切点execution(* *(..)) && @annotation(logTime)虽然看起来匹配所有方法,但Spring AOP会在底层自动过滤掉非公共方法,所以即使表达式匹配,也不会触发切面逻辑。这是Spring AOP的内置行为,和切点表达式本身无关。
内容的提问来源于stack exchange,提问作者Sonu
相关产品推荐
相关产品推荐

