前言:
目前各位老铁们对“aop代理机制”大体比较看重,大家都想要知道一些“aop代理机制”的相关知识。那么小编也在网络上汇集了一些关于“aop代理机制””的相关知识,希望小伙伴们能喜欢,小伙伴们快快来了解一下吧!引言
Spring的AOP 主要是由切面和代理对象两块内容实现的,切面以及代理对象的初始化原理已经在Spring AOP 实现原理解析 分析过了,现在就从源码方面来分析一下代理对象在spring中如何工作的[奋斗]
代理对象执行机制
下面我们直接通过JdkDynamicAopProxy源码来对代理对象的运行机制进行解析,直接上源码:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Object target = null; try { //equal方法不进行特殊处理,直接调用equals方法 if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { return equals(args[0]); } //hashCode方法不进行特殊处理,直接调用hashCode方法 else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { return hashCode(); } //还有一些其他不需要代理的方法,无关主流程,省略 Object retVal; //判断@EnableAspectJAutoProxy是否配置exposeProxy = true if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); //从缓存中获取增强器,并将增强器转化为方法拦截器链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //因为我们配置了切面,所以拦截器链不为空,内部省略 if (chain.isEmpty()) { } else { // 创建拦截器链方法调用器,这个调用器就充分的展示了Aop使用了所谓的责任链模式 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); /* 这里就是循环的调用拦截器链中各增强器的方法,aop的切面代理功能就是在这个方法上 实现的,调用的ReflectiveMethodInvocation.proceed方法,此方法执行完成后, 切面方法以及被监控bean实际需要执行的方法在此都会被执行,下方有具体实现源码 注意:本次分析的是jdk动态代理,cglib代理逻辑和jdk类似,不过源码不同*/ retVal = invocation.proceed(); } //获取方法返回值 Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { //如果需要返回代理对象,则直接返回代理对象 retVal = proxy; } return retVal; } }/*ReflectiveMethodInvocation.proceed方法,注意此方法会被多次调用,每次调用对象都是同一个对象,即JdkDynamicAopProxy.invoke方法 下面这行代码创建的对象,需要记住*///MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);public Object proceed() throws Throwable { /*currentInterceptorIndex初始值为-1,interceptorsAndDynamicMethodMatchers长度为5, 即当前被监控的bean的所有增强器加上系统自带的增强器,我们分别配置了 Before、After、AfterReturning、AfterThrowing四个增强器, 系统自带了一个advisor增强器,这段逻辑的意思为,只有所有的增强器对应的监控方法 (invoke)过后,才会执行真实的方法,即invokeJoinpoint()*/ if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } /*从缓存中获取对应的方法拦截器,分别为: ExposeInvocationInterceptor-系统自带拦截器 MethodBeforeAdviceInterceptor-前置通知拦截器 AspectJAfterAdvice-后置通知增强器 AfterReturningAdviceInterceptor--返回通知拦截器 AspectJAfterThrowingAdvice--异常通知拦截器*/ Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //上述5中拦截器均未实现或者继承InterceptorAndDynamicMethodMatcher,故省略内部逻辑 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { } else { //调用拦截器对应的invoke方法,下面会按调用顺序将五种拦截器的源码附上 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }//ExposeInvocationInterceptor.invoke方法public Object invoke(MethodInvocation mi) throws Throwable { //防止调用过程中方法调用器被修改,因此此处先存起来,执行拦截器执行结束后,将方法调用器重新赋值 MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { /*调用MethodInvocation.proceed方法,此次调用后,invocation对象 内部属性currentInterceptorIndex会变成1,当proceed方法再次执行到88行代码时, interceptorOrInterceptionAdvice对象就已经变成MethodBeforeAdviceInterceptor, 即所谓的前置通知拦截器*/ return mi.proceed(); } finally { invocation.set(oldInvocation); } }//MethodBeforeAdviceInterceptor.invokepublic Object invoke(MethodInvocation mi) throws Throwable { /*此处执行@Before修饰的切面方法,这也解释了@Before修饰的方法块,永远在 业务方法执行钱会执行了*/ this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); /*继续调用MethodInvocation.proceed方法,此次调用后,invocation对象 内部属性currentInterceptorIndex会变成2,当proceed方法再次执行到88行代码时, interceptorOrInterceptionAdvice对象就已经变成AspectJAfterAdvice, 即所谓的后置通知拦截器*/ return mi.proceed(); }//AspectJAfterAdvice.invokepublic Object invoke(MethodInvocation mi) throws Throwable { try { /*继续调用MethodInvocation.proceed方法,此次调用后,invocation对象 内部属性currentInterceptorIndex会变成3,当proceed方法再次执行到88行代码时, interceptorOrInterceptionAdvice对象就已经变成AfterReturningAdviceInterceptor, 即所谓的返回通知拦截器*/ return mi.proceed(); } finally { /*此处时执行@After注解修饰的切面,这也说明了,为什么@After修饰的方法块 永远在最后且一定会执行*/ invokeAdviceMethod(getJoinPointMatch(), null, null); } }//AfterReturningAdviceInterceptor.invokepublic Object invoke(MethodInvocation mi) throws Throwable { /*继续调用MethodInvocation.proceed方法,此次调用后,invocation对象 内部属性currentInterceptorIndex会变成4,当proceed方法再次执行到88行代码时, interceptorOrInterceptionAdvice对象就已经变成AspectJAfterThrowingAdvice, 即所谓的异常通知拦截器*/ Object retVal = mi.proceed(); /*如果上一步执行正常,则会执行@AfterReturning注解修饰的方法快,加入上一步执行出现异常, 则@AfterReturning不会执行*/ this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }//AspectJAfterThrowingAdvice.invoke方法public Object invoke(MethodInvocation mi) throws Throwable { try { /*继续调用MethodInvocation.proceed方法,此次调用后,invocation对象 内部属性currentInterceptorIndex会变成5,当proceed方法再次执行到72行代码时, if判断结果为true,则会真正开始执行被监控bean对应的业务方法*/ return mi.proceed(); } catch (Throwable ex) { //判断当前类型是否需要执行异常通知方法 if (shouldInvokeOnThrowing(ex)) { //执行@AfterThrowing修饰的代码块,这样就可以在业务代码执行异常之后,去做一些特殊处理 invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }
以上就是Spring aop 代理的实际运行原理,主要使用的是责任链模式以及代理模式两种设计模式,从而高效达到一个动态实时代理的功能[灵光一闪]
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #aop代理机制