上一篇分享了,spring 中bean实例的循环依赖,今天开始分享解析AOP 源码。
1、首先从源码中AOP 的入口方法开始, AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory 类中的方法如下:
try { // IOC 依赖注入的核心方法 populateBean(beanName, mbd, instanceWrapper); //bean 实例化和Ioc依赖注入完以后的调用,这里就是AOP 的入口,点击进入 exposedObject = initializeBean(beanName, exposedObject, mbd); }
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
来到这个方法:
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) {//获取所有的BeanPostProcessors,进行遍历 //这是一个 BeanPostProcessor 接口的埋点运用,进入后选择实现类--> Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
2、进入接口后ctrl+t 显示多个实现类:
很明显我们进入 AbstractAutoProxyCreator 类,
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey);//核心方法在这,点击进入--> } } return bean; }
来到:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } //该方法去寻找advisor 切面,如果这个bean有advice的话,就创建当前bean的代理,点击进入--> Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //如果有切面,则生成该bean的代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //把被代理对象bean实例封装到SingletonTargetSource对象中 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
3、进入 AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator 的 getAdvicesAndAdvisorsForBean 方法:
@Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class> beanClass, String beanName, @Nullable TargetSource targetSource) { //寻找到合格的切面,收集起来,点击进入--> Listadvisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
来到-->
protected ListfindEligibleAdvisors(Class> beanClass, String beanName) { //找到候选的切面,其实就是一个寻找有@Aspectj 和相关 注解的过程,把工程中所有有这个注解的类封装成Advisor返回,点击进入--> List candidateAdvisors = findCandidateAdvisors(); //判断上面收集的切面是否作用在当前 beanClass 上面(即是否在:pointcut 的表达式目录里),就是一个匹配过程。 List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //对有@Order@Priority进行排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
4、ctrl+t 显示:很明显 进入 AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator 类
的
@Override protected ListfindCandidateAdvisors() { //可以不看 // Add all the Spring advisors found according to superclass rules. List advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. //这里开始创建候选的切面,点击进入--> if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
5、来到 BeanFactoryAspectJAdvisorsBuilder
public ListbuildAspectJAdvisors() { List aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List advisors = new ArrayList<>(); aspectNames = new ArrayList<>(); //获取spring容器中的所有bean的名称BeanName,并遍历循环 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. Class> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //判断类上是否有@Aspect注解,如果有,该类就很可能有切面 if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //创建获取有@Aspect注解类的实例工厂,负责获取有@Aspect注解类的实例 MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //创建并获取切面advisor对象,点击进入--> List classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List advisors = new ArrayList<>(); for (String aspectName : aspectNames) { List cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }
6、ctrl+T 进入 ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable 类的
getAdvisors 方法:
@Override public ListgetAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //从工厂中获取有@Aspect注解的类Class Class> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //从工厂中获取有@Aspect注解的类的名称 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); validate(aspectClass); //创建工厂的装饰类,获取实例只会获取一次 // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List advisors = new ArrayList<>(); //这里循环没有@Pointcut注解的方法 for (Method method : getAdvisorMethods(aspectClass)) { //重点分析看看 ,点击进入---> Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } //判断属性上是否有引介注解 // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { //判断属性上是否有DeclareParents注解,如果有返回切面 Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
来到 getAdvisor 方法:
@Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //获取pointCut对象,最重要的是从注解中获取表达式,即需要代理增强的类所在的目录,点击进入--> AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } //创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice //这里pointCut是expressionPointcut, advice 增强方法是 candidateAdviceMethod,点击--> return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }
来到getPointcut 方法:
@Nullable private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class> candidateAspectClass) { //从候选的增强方法里面 candidateAdviceMethod 找有有注解 //Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class //并把注解信息封装成AspectJAnnotation对象,点击进入--> AspectJAnnotation> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } //创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class>[0]); ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; }
7、进入 AbstractAspectJAdvisorFactory implements AspectJAdvisorFactory 类中的
findAspectJAnnotationOnMethod 方法:
@SuppressWarnings("unchecked") @Nullable protected static AspectJAnnotation> findAspectJAnnotationOnMethod(Method method) { for (Class> clazz : ASPECTJ_ANNOTATION_CLASSES) { //找到Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class //注解的方法,并且把注解里面的信息封装成AspectJAnnotation对象,点击--》 AspectJAnnotation> foundAnnotation = findAnnotation(method, (Class) clazz); if (foundAnnotation != null) { return foundAnnotation; } } return null; }
来到:findAnnotation方法
@Nullable private static AspectJAnnotation findAnnotation(Method method, Class toLookFor) { //找的规则就是找注解的父注解,递归的方式去找,直到找到目标注解为止 A result = AnnotationUtils.findAnnotation(method, toLookFor); if (result != null) { //把注解里面的信息解析出来,然后包装成AspectJAnnotation对象 return new AspectJAnnotation<>(result); } else { return null; } }
8、回到上面:点击 InstantiationModelAwarePointcutAdvisorImpl 对象实现类的构造方法,InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.aspectJAdvisorFactory = aspectJAdvisorFactory; this.aspectInstanceFactory = aspectInstanceFactory; this.declarationOrder = declarationOrder; this.aspectName = aspectName; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; //创建advice对象 点击进入--》 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } }
来到:
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { //创建Advice对象, ,如上: Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return (advice != null ? advice : EMPTY_ADVICE); }
9、ctrl+t getAdvice 进入 ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable
@Override @Nullable public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //获取有@Aspect注解的类 Class> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); validate(candidateAspectClass); //找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型 AspectJAnnotation> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } // If we get here, we know we have an AspectJ method. // Check that it's an AspectJ-annotated class if (!isAspect(candidateAspectClass)) { throw new AopConfigException("Advice must be declared inside an aspect type: " + "Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); } if (logger.isDebugEnabled()) { logger.debug("Found AspectJ method: " + candidateAdviceMethod); } AbstractAspectJAdvice springAdvice; //根据不同的注解类型创建不同的advice类实例 switch (aspectJAnnotation.getAnnotationType()) { case AtPointcut: if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; case AtAround: //实现了MethodInterceptor接口 springAdvice = new AspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtBefore: //实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口 springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: //实现了MethodInterceptor接口 springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: //实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口 springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: //实现了MethodInterceptor接口 springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break; default: throw new UnsupportedOperationException( "Unsupported advice type on method: " + candidateAdviceMethod); } // Now to configure the advice... springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } //计算argNames和类型的对应关系 springAdvice.calculateArgumentBindings(); return springAdvice; }
10、到这里AOP 的切面已经生成,可以去创建代理了,入口如下:
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //如果有切面,则生成该bean的代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //把被代理对象bean实例封装到SingletonTargetSource对象中,代理类的调用入口--》下篇介绍 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; }
11、由于时间问题,代理类的调用流程下一篇解析,敬请期待!