一、生成代理对象
spring对象初始化过程(遗记了能够看这里:对象初始化惯例流程),属性赋值后对对象做代理加强——这是AOP得以实现的根底。
源码入口如下:
Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 属性赋值办法 populateBean(beanName, mbd, instanceWrapper); // ## 此处做代理加强 exposedObject = initializeBean(beanName, exposedObject, mbd);}
咱们看下办法实现:
initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // 对象初始化前置处理器 wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); // 执行初始办法 this.invokeInitMethods(beanName, wrappedBean, mbd); // ## 对象初始化后置处理器 wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}
跟踪后置处理器
的执行链路:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitializationorg.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitializationorg.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessaryObject wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // ## 1.获取Advisor Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // ## 2.创立AOP代理对象 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));}
别离察看这两步的实现。
1.获取Advisor
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBeanorg.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors// 咱们察看“注解实现”org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisorsorg.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisorsList<Advisor> buildAspectJAdvisors() { Class<?> beanType = this.beanFactory.getType(beanName); // ### A.什么样的对象是Advisor? if (this.advisorFactory.isAspect(beanType)) { // ### B.Advisor对象如何创立 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); }}
从这部分源码又衍生出几个问题。
A.什么样的对象是Advisor
答:被@Aspect对象润饰的对象是Advisor
org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspectorg.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#hasAspectAnnotationprivate boolean hasAspectAnnotation(Class<?> clazz) { // 源码是这么写的 return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);}
再思考一下,应用过程中被@Aspect注解润饰的对象是什么?
答案是“一个切面申明”,比方上面的例子。
#### 这是一个切面申明的例子,非spring源码 ####@Aspect@Componentpublic class TransactionAop { @Pointcut("execution(* com.jiuxian..service.*.*(..))") public void pointcut() { } @Before("pointcut()") public void beginTransaction() { System.out.println("before beginTransaction"); } @After("pointcut()") public void commit() { System.out.println("after commit"); }}
于是大胆推断——Advisor是不是一个切面对象的封装?
接下来,通过Advisor的创立过程来验证这个推断是否正确。
B.Advisor对象如何创立
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisorsList<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory){ // ** 代码1:获取了某种办法 ** for (Method method : getAdvisorMethods(aspectClass)) { // ** 代码2:依据`代码1`的办法构建Advisor ** Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); }}
代码1:获取的某种办法是什么?
ReflectionUtils.doWithMethods(aspectClass, method -> { // 获取非@Poincut注解润饰的所有办法(即@Before、@After注解润饰的办法) if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); }});
代码2:依据代码1
的办法构建的Advisor到底是什么?
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisorAdvisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { // == 获取切面信息 AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } // == 返回Advisor的实现 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);}
Advisor由InstantiationModelAwarePointcutAdvisorImpl实现,联合代码1来看,Advisor实质是对一个切面办法(@Before、@After等润饰的办法)的封装
之前的推断有些许偏差……
最初咱们看一下InstantiationModelAwarePointcutAdvisorImpl
是怎么获取Advice的
C.Advisor获取Advice
org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#getAdviceorg.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#instantiateAdvice// == 每个注解都对应着一种具体的Advice实现switch (aspectJAnnotation.getAnnotationType()) { case AtAround: springAdvice = new AspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtBefore: springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break;}
2.创立AOP代理对象
后面纵深过大,简略总结一下:
咱们用大段篇幅解释了wrapIfNecessary办法的“代码1”局部——这个specificInterceptors数组,其实就是切面中的切面办法(各种@Before、@After注解润饰的办法)的封装。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessaryObject wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // ## 1.获取Advisor Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); // ## 2.创立AOP代理对象 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));}
接下来,进入“代码2”局部,看看AOP代理是如何创立的!
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxyorg.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)public Object getProxy(@Nullable ClassLoader classLoader) { //== A.先创立AopProxy对象,实质就是new JdkDynamicAopProxy(config) return new JdkDynamicAopProxy(config) //== B.再调用JdkDynamicAopProxy的getProxy()办法 .getProxy(classLoader);}
public Object getProxy(@Nullable ClassLoader classLoader) { // ## 第三个参数InvocationHandler传入的是this,所以被代理对象理论执行的是本类的invoke()办法 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);}
代理执行逻辑,下一章再剖析。
二、AOP执行
目前咱们曾经晓得,spring对象初始化后会对申明AOP切面的对象作动静代理。
这样在对象办法执行时,会执行相应的代理办法。
而代理对象又蕴含全副的切面办法封装和切面申明,剩下的只是把它们关联起来。
本章对这部分逻辑加以分析。
// ## 1.构建责任链(全副的advice)List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// ## 2.责任链调度MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);retVal = invocation.proceed();
1.构建责任链
org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdviceorg.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdviceif (advisor instanceof PointcutAdvisor) { PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { // 获取办法匹配器@Pointcut的expression MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; // 依据expression表达式匹配指标办法(以后执行的办法) match = mm.matches(method, actualClass); if (match) { // 匹配上了,返回办法的全副拦截器(advice的封装) MethodInterceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } }}
2.责任链调度
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed// 构造函数中赋值chain,办法拦截器 -> adviceprotected final List<?> interceptorsAndDynamicMethodMatchers;// chain的索引private int currentInterceptorIndex = -1;-------- ## 以上为属性 ## --------------// ### 这是一个递归办法public Object proceed() throws Throwable { // == 1.曾经是chain中的最初一个拦截器,则执行原办法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return this.invokeJoinpoint(); } // == 2.否则,执行过滤器办法 else { // 索引自增,获取链中的以后拦截器 Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); // ## 拦截器执行(不同的拦截器有不同的实现) return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); }}
最初察看两种不同的拦截器实现吧。
before拦截器
// == before拦截器(告诉)org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke{ // 先执行拦截器 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 再执行办法(递归调用,代码去执行ReflectiveMethodInvocation#proceed) return mi.proceed();}
after拦截器
// == after拦截器(告诉)org.springframework.aop.aspectj.AspectJAfterAdvice#invoke{ Object var2; try { // 先执行办法(递归调用,代码去执行ReflectiveMethodInvocation#proceed) var2 = mi.proceed(); } finally { // 再执行拦截器实现 this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); } return var2;}
附录
P6-P7常识合辑