关于 Spring AOP 中,包含参数的成员方法的调用,出现 NoSuchMethodException 的研究
2018-03-21 00:00
561 查看
##关于 Spring AOP 中,包含参数的成员方法的调用,出现 NoSuchMethodException 的研究
网上看了一大堆,大都是关于init方法和构造方法的情况,可能此处有些特殊。发出来交流一下。
Spring版本 - spring-framework-2.5.6-with-dependencies
在使用中,偶然用到一个单独的有参数的方法的调用,包了错误
NoSuchMethodException
首先不是修饰符的问题 - 因为内部有暴力访问机制
源码 ——
package org.springframework.util; public abstract class ReflectionUtils /** * Make the given method accessible, explicitly setting it accessible if necessary. * The <code>setAccessible(true)</code> method is only called when actually necessary, * to avoid unnecessary conflicts with a JVM SecurityManager (if active). * @param method the method to make accessible * @see java.lang.reflect.Method#setAccessible */ public static void makeAccessible(Method method) { if (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) { method.setAccessible(true); } }
在Spring的AOP中会自动完成方法的切入点表达式的匹配
mi Cglib2AopProxy$CglibMethodInvocation (id=131) org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(insert)
相关的关键生成类
package org.springframework.aop.aspectj; public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor /** * Return the ProceedingJoinPoint for the current invocation, * instantiating it lazily if it hasn't been bound to the thread already. * @param rmi the current Spring AOP ReflectiveMethodInvocation, * which we'll use for attribute binding * @return the ProceedingJoinPoint to make available to advice methods */ protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) { return new MethodInvocationProceedingJoinPoint(rmi); } org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(insert)
后期会在此处使用
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { [org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(insert)] Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterTypes().length == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); // TODO AopUtils.invokeJoinpointUsingReflection return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex); } catch (InvocationTargetException ex) { java.lang.reflect.InvocationTargetException throw ex.getTargetException(); } }
最终可能出现报错的产出位置
package org.springframework.aop.aspectj; public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); return invokeAdviceMethod(pjp, jpm, null, null); } 重点看pmi 与pjp
解决办法 -
由于这种机制的存在,主要是引起通知方法的调用和匹配
在其内部,获取有参方法会先匹配切入点
而切入点的自动生成机制比较简单
例如
本应该是 ...insert(java.lang.String); target is of class ... 结果生成的切入点表达式为 org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(insert)
那么,在此处,无参的方法为了使用是必须出现的
但是如果本身并不需要调用的话,那么就没有什么意义
如同AOP的注解中定义的切入点表达式一般,并无任何意义,方法体不调用,是不会执行的。
只是避免了内部机制实现的报错而已。
由于当前项目配置较为驳杂,后期有空单独把这一部分抽取出来进行测试研究,如有更好的见解,欢迎评论交流。
如需要转载
请注明文章出处
https://my.oschina.net/u/3032872/blog/1648360
谢谢~
相关文章推荐
- spring的aop拦截action中的方法会报java.lang.NoSuchMethodException: $Proxy97.test()异常
- Spring的bean中直接调用成员变量出现nullpointexception的解决方法
- 关于Service方法调用时出现org.apache.ibatis.binding.BindingException错误的可能原因
- 关于使用Spring声明式事务时,在类的内部方法互相调用时,Spring无法拦截内部方法调用,导致事务不起作用的问题研究
- Intellij IDEA中Spring配置aop增强事务 出现BeanCreationException异常处理方法
- C#关于参数为null(空值)的方法调用,重载顺序选择彻底研究
- java自定义类型参数的方法时出现NoSuchMethodException
- Java中反射调用私有方法出现NoSuchMethodException
- java.lang.IllegalAccessException Action中的方法调用了,却不出现结果 spring注入值为null
- 关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序的研究
- Spring3.2 Contorller单元测试参数问题: java.lang.NoSuchMethodException
- 关于注解实现Aop出现 Spring error at ::0 can't find referenced pointcut myMethod的解决
- 关于oracle存储过程调用问题。execute method error : DataAccessException,或者时参数个数或类型错误,等等
- 关于Silverlight中WebService调用出现CommunicationException The remote server returned an error: NotFound
- 关于jquery对象的remove参数中出现伪位置类选择器,出现非预期结果的研究
- 调用Type.InvokeMember()时出现MissingMethodException
- 通过 spring/web services 调用 jdbcTemplate sql参数没填写出现的错误提示
- 在Silverligh中调用J“.NET研究”avascript (四种调用方法+简单与复杂参数的传递)
- 关于Flex与Spring整合RemoteObject调用Java方法找不到自定义通道的解决方法
- 那些关于java.lang.NoSuchMethodException: