最近回味SSH框架,发现同事的小bug NoSuchMethod $Proxy.add(), 解决办法和根本原因

本文探讨了在使用Spring4+Hibernate5+Struts2框架时遇到的AOP切点配置问题,详细分析了错误原因,并提供了两种解决方案:调整切点配置避免拦截Action类或启用CGLIB代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

选用框架 Spring4+hibernate5+struts2 . 

 原因 : 在配置Aop切点的时候把Action类也拦截了 , 自定义的action是继承自actionSupport的


<aop:pointcut id="" expression="execution(com.XX..*(..))">

最后发现报了这样一个异常: 

java.lang.NoSuchMethodException: $Proxy5.add()
at java.lang.Class.getMethod(Class.java:1605)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:55)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:41)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
.........


解决方式:

一 . 不要拦截action类 即在execution中写具体的包不要把action包含进去

二.在 <aop:config ,,>上添加 <aop:config proxy-target-class="true"> 即可


原因分析:
分析上述异常 可知  找不到此方法add() .但在action类中 确实有这个方法, 重点就在于 是你的自定义的action类中有此方法,

由于采用的是继承actionSupport类  ,我们看一看源码



   Action是实现了几大接口  . 我们知道 JDK默认的生成代理对象的方案 也就是在JVM内部动态生成class字节码文件的方式去生成代理对象. 是需要代理实现了接口的类的,实现生成代理对象的底层我们下回再讨论。 针对这个问题,那就好办了, add()方法是自定义action中的方法,而实现的接口中并没有add()方法 。而spring默认使用的就是JDK的动态代理方式去实现aop编程,自然在这种情况下,是找不到$Proxy对象中的add()方法的! 故报错 ,如何解决呢?还有另外一种可以不针对接口的代理方式 CGLIB 动态代理: .CGLIB(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类. 所以可以在<aop:config 上添加 一句: 

proxy-target-class="true" 就是开启默认使用cglib方式生成代理对象 . 如果没有开启,那么spring会根据类是否实现接口来判断使用何种方式生成代理对象!  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值