一、@EnableAspectJAutoProxy注解   在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什么?接下来分析下:   @EnableAspectJAutoProxy点进去如下:   此时看到了我们非常熟悉的@Import注解,@Import(AspectJAutoProxyRegistrar.class),进入到AspectJAutoProxyRegistrar发现实现了ImportBeanDefinitionRegistrar如下: 复制代码 class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { /** * Register, escalate, and configure the AspectJ auto proxy creator based on the value * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing * {@code @Configuration} class. */ @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } } 复制代码   会调用registerBeanDefinitions方法,跟进到这个方法里面,主要作用就是往Spring容器中注册AnnotationAwareAspectJAutoProxyCreator的Bean的定义信息: 二、AnnotationAwareAspectJAutoProxyCreator继承图 三、AnnotationAwareAspectJAutoProxyCreator创建代理   首先AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了BeanFactoryAware接口:   所以在创建AnnotationAwareAspectJAutoProxyCreatorBean的过程中初始化方法里面会调用setBeanFactory方法:   在setBeanFactory方法里面调用initBeanFactory来初始化通知者检索帮助类,后面检索通知会用到。 复制代码 protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); } 复制代码   其次AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口:   该接口定义了2个方法:postProcessBeforeInstantiation和postProcessAfterInstantiation,所以AbstractAutoProxyCreator实现了这2个方法;还记得我们在Spring IoC源码解析篇分析到如下代码:   resolveBeforeInstantiation方法进去就会调到AbstractAutoProxyCreator的postProcessBeforeInstantiation方法 复制代码 /** * 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后) * AOP解析切面以及事务解析事务注解都是在这里完成的 * @param beanClass 当前正在创建的Bean的Class对象 * @param beanName beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { //构建我们的缓存key Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //如果被解析过直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } /** * 判断是不是基础的Bean(Advice、PointCut、Advisor、AopInfrastructureBean)是就直接跳过 * 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息(并且把我们的切面信息进行缓存),而事务在这里是不会解析的) */ if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; } 复制代码   接下来进入到shouldSkip(beanClass, beanName)方法(很重要): 复制代码 protected boolean shouldSkip(Class beanClass, String beanName) { /** * 找到候选的Advisors(通知者或者增强器对象) */ List candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); } 复制代码   接下来看如何找候选的Advisors,findCandidateAdvisors()方法如下: 复制代码 @Override protected List findCandidateAdvisors() { //找出事务相关的advisor List advisors = super.findCandidateAdvisors(); //找出Aspect相关的信息之后封装为一个advisor if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } //返回我们所有的通知 return advisors; } 复制代码   第一步找事务相关的Advisor: 复制代码 protected List findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); /** * 通过通知者检测帮助类来帮助我们找到通知 * */ return this.advisorRetrievalHelper.findAdvisorBeans(); } 复制代码   第二步找构建AspectJAdvisors: 复制代码 /** * 去容器中获取到所有的切面信息保存到缓存中 */ public List buildAspectJAdvisors() { List aspectNames = this.aspectBeanNames; //缓存字段aspectNames没有值 注意实例化第一个单实例bean的时候就会触发解析切面 if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { //用于保存所有解析出来的Advisors集合对象 List advisors = new ArrayList<>(); //用于保存切面的名称的集合 aspectNames = new ArrayList<>(); /** * AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再 * 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。 * 但是事务功能不一样,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。 * 所以Spring在事务模块中没有加入缓存来保存我们的事务相关的advisor */ String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); //遍历我们从IOC容器中获取处的所有Bean的名称 for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } //通过beanName去容器中获取到对应class对象 Class beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } //根据class对象判断是不是切面 @Aspect if (this.advisorFactory.isAspect(beanType)) { //是切面类 //加入到缓存中 aspectNames.add(beanName); //把beanName和class对象构建成为一个AspectMetadata AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { //构建切面注解的实例工厂 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; } 复制代码   ① org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory#isAspect:   ② 真正的去获取我们的Advisor,this.advisorFactory.getAdvisors(factory)方法如下: 复制代码 @Override public List getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取我们的标记为Aspect的类 Class aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取我们的切面类的名称 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //校验我们的切面类 validate(aspectClass); //我们使用的是包装模式来包装我们的MetadataAwareAspectInstanceFactory构建为MetadataAwareAspectInstanceFactory 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 (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } 复制代码   获取切面上的通知方法,并按照规则排序,getAdvisorMethods(aspectClass): 复制代码 private List getAdvisorMethods(Class aspectClass) { final List methods = new ArrayList<>(); ReflectionUtils.doWithMethods(aspectClass, method -> { if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) { methods.add(method); } }); methods.sort(METHOD_COMPARATOR); return methods; } 复制代码   排序(该顺序在代理调用的时候会用到)规则如下:   根据通知的方法创建增强器:getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName)如下: 复制代码 public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //切面的方法上构建切点表达式 AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } //实例化我们的切面通知对象 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); } 复制代码   实例化我们的切面通知对象,new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,this, aspectInstanceFactory, declarationOrderInAspect, aspectName): 复制代码 public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //当前的切点表达式 this.declaredPointcut = declaredPointcut;