《Spring系列》第13章 Aop切面(二) 代理创建

文章详细剖析了SpringAOP的源码,从启用AOP的注解`@EnableAspectJAutoProxy`开始,解释了如何向IOC容器中注册后置处理器,以及后置处理器如何在Bean创建时生成代理对象。文章还详细介绍了获取增强器的逻辑,包括切点匹配、增强器排序等,并探讨了根据增强器创建代理的过程,包括JDK动态代理和CGLIB代理的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本篇文章主要介绍AOP的源码,要想看懂AOP,那么就看AOP给容器中注入了什么组件,这个组件什么时候工作,这个组件的功能是什么?

  1. @EnableAspectJAutoProxy会向IOC容器中注入一个后置处理器,它会在Bean的创建过程进行加工
  2. 当我们获取Bean的时候,因为已经存在Aop注入的后置处理器,会在Bean的创建阶段生成代理对象
  3. 最终生成的Bean代理对象,里面会是一个层层代理的链式结构,因为Aop里面的增强方法是存在顺序的,所以这里也是按照顺序执行
  4. 当调用目标方法的时候,就会按照顺序依次执行增强方法和目标方法

一、@EnableAspectJAutoProxy

1.注解引入了哪个类

当使用AOP的时候,会通过注解@EnableAspectJAutoProxy来开启AOP,那么这个注解做了些什么呢?看一下其源码,发现通过@Import注解引用了AspectJAutoProxyRegistrar.class,其最终目的就是注入了这个类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) // 在这里引入了一个类
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar 是上面注解导入的一个类,它实现了ImportBeanDefinitionRegistrar接口,该接口同样也是Spring提供的扩展点,它可以把自定义的BeanDefinition注册到Spring容器中。

那么该类中主要做了2件事

  1. 通过AopConfigUtils注册了一个BeanDefinition,具体为AnnotationAwareAspectJAutoProxyCreator
  2. 根据@EnableAspectJAutoProxy设置的属性,进行相应的操作
// 导入的这个类实现了 ImportBeanDefinitionRegistrar 接口
// 该接口可以将自定义的组件添加到容器中
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

         // 通过Aop工具类 `注册切面注解自动代理创建器当其需要的时候`  这也是方法名的意思
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

         // 获取@EnableAspectJAutoProxy注解的属性  在其注解里面可以设置2个属性
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
         // 通过这2个属性 在进行响应的处理
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
}

上面的方法中看到会借助AopConfigUtils类来注册BeanDefinition,进入对应的方法里面可以看到注册的类为AnnotationAwareAspectJAutoProxyCreator

	// 第1步:首先会调用到这里
    @Nullable
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
        return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
    }
    
    // 第2步:再次会进入到这里
    @Nullable
    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
        // 在这里看到注入的Bean为 AnnotationAwareAspectJAutoProxyCreator.class
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

	// 第3步
	@Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        // 判断是否包含这个名称为 internalAutoProxyCreator的Bean
        if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
            // 获取到Bean
            BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
            // 如果全限定类名是否相同 也就是上面的名字相同,那么需要在判断类型
            if (!cls.getName().equals(apcDefinition.getBeanClassName())) {// 当不相同的时候
                int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                int requiredPriority = findPriorityForClass(cls);
                // 判断优先级
                if (currentPriority < requiredPriority) {
                    apcDefinition.setBeanClassName(cls.getName());
                }
            }

            return null;
        } else {
            // 不存在则创建Bean
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", -2147483648);
            beanDefinition.setRole(2);
            registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
            return beanDefinition;
        }
    }

2.引入类介绍

通过上面的内容得知,@EnableAspectJAutoProxy注解最终会向Bean的定义信息里面注册一个AnnotationAwareAspectJAutoProxyCreator类,其对应的beanNameorg.springframework.aop.config.internalAutoProxyCreator

通过下面的类图可以看出,AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,证明它是一个后置处理器,不仅需要把它注入到IOC容器中,还需要把它注入到BeanFactory后置处理器集合中

> 注入到后置处理器集合中

实现逻辑的方法为refresh() -> registerBeanPostProcessors() ,它负责了2件事情:

  1. 把后置处理器存入IOC容器中,所有的bean都要注入到容器中,这是必须的
  2. 把后置处理器按照优先级规则存入beanFactory
// PostProcessorRegistrationDelegate

// 下面的代码看着很长,其实仔细看很简单,主要就是注册后置处理器,但是需要按照优先级分成三组,顺序注册
// 大体的执行流程未:
//	1) 先获取IOC容器已经定义了的需要创建对象的所有BeanPostProcessor
//	2) 给容器中加别的BeanPostProcess
//  3) 优先注册实现了 PriorityOrdered接口的BeanPostProcessor
//  4) 再给容器中注册实现了Ordered接口的BeanPostProcessor
//  5) 注册没实现优先级接口的BeanPostProcessor
//  6) 注册BeanPostProcessor 实际上就是通过getBean()创建BeanPostProcessor对象,保存在容器中
//	7) 把BeanPostProcessor注册到BeanFactory中
	   
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
		
         // 获取到工厂里面的所有BeanPostProcessor
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
         // 数量
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
         List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
         // 遍历
		for (String ppName : postProcessorNames) {
             // 实现PriorityOrdered接口的后置处理器添加到priorityOrderedPostProcessors
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
                  // 实现MergedBeanDefinitionPostProcessor接口的添加到internalPostProcessors
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
             // 实现Ordered接口的添加到orderedPostProcessorNames
             // 像使用AOP需要注入的【AnnotationAwareAspectJAutoProxyCreator】在顶层实现了Ordered接口
             // 所以会在这里
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
                 // 未实现排序的处理器
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
         // 注册实现PriorityOrdered接口的后置处理器
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
         // 注册实现Ordered接口的后置处理器
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
         // 注册未实现排序的处理器
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
         // 最终 注册实现MergedBeanDefinitionPostProcessor接口的
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners, 
		// moving it to the end of the processor chain (for picking up proxies etc).
         // 重新注册后置处理器把内部Bean检测为ApplicationListeners
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

在这里插入图片描述

二、获取增强器

带着问题看源码

AOP底层是借助的后置处理器,这个已经说了很多遍了,上面介绍的AnnotationAwareAspectJAutoProxyCreator类实现了BeanPostProcessor,并且注入到容器中了,剩下的肯定使用,那么我们需要关心的无非是几个问题:

  1. 创建成AOP代理对象的方法入口在哪里?
  2. 获取该bean可以应用的增强器
  3. 代理对象创建过程
  4. 创建后的代理对象长啥样?

1.入口方法

既然是后置处理器,肯定是bean初始化的时候,会创建成代理对象,那么bean的初始化也分情况:

  1. 如果是普通的bean创建,那么会在doCreateBean() -> initializeBean(),当创建bean以后,初始化的时候,会执行对应的后置处理器
  2. 如果是循环依赖的bean创建,那么会在doCreateBean() -> getEarlyBeanReference(),在这里也会执行后置处理器

上面我在Debug源码的时候只试了这2种情况,可能还要其它的入口,但到不管有多少个入口,到最后都会到1个地方负责创建代理,那就是AnnotationAwareAspectJAutoProxyCreator类,找到其重写后置处理器接口的方法就好了。

在源码翻阅的时候,发现其中并没有,但是在其父类AbstractAutoProxyCreator,其中存在重写的postProcessAfterInitialization()

在这里插入图片描述

2.获取该bean可以应用的增强器

> 整体逻辑

AOP又给我们提供了各种类型的切面,当需要把bean给创建成代理对象,整体逻辑如下:

  1. 创建前需要存在各种特殊判断,判断这个bean到底是否需要创建代理对象,排除一些特殊情况,当判断通过,接下来就是开始创建代理
  2. 获取代码设置的全部增强器,还有各种切入点Pointcut,这些第一次获取以后肯定是缓存起来的
  3. 从全部的增强器中获取到该bean可以使用的增强器
  4. 对增强器进行排序

> wrapIfNecessary()

通过上面我们看到,创建代理对象都是走到AbstractAutoProxyCreator#wrapIfNecessary()这个类的后置处理器方法中

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      // 根据给定bean的class和name构建出一个key,格式: beanClassName_beanName
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      // 可能存在循环依赖,判断该bean是否已经提前暴露,  存在这里就不用创建代理对象了
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         // 适合被代理,则需求封装指定bean
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

wrapIfNecessary()这个方法通过名字也可以看出意思来,如果该bean可以被代理,那就创建

// 在这里面的类代表无须再次尝试创建AOP代理对象,  包括已经创建完的和不需要创建的
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   // 1.如果已经处理过
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   // 2.代表该bean无需增强
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   // 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }
	
   // 4.获取当前bean的Advices和Advisors
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   // 5.如果存在增强器则创建代理
   if (specificInterceptors != DO_NOT_PROXY) {
      // 代表该bean已经处理了
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      // 创建搭理
      Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      // 创建完代理后,将cacheKey -> 代理类的class放到缓存
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   // 6.标记为无需处理
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

> 不能创建代理对象前的特殊情况

wrapIfNecessary()前会有几个方法执行,负责判断是否可以把当前bean创建成代理对象,初始化的时候肯定会有一些特殊情况存在,需要特殊排除

isInfrastructureClass() 排除基础设置类

是否是基础配置类,一些固定的类不能被代理

	@Override
	protected boolean isInfrastructureClass(Class<?> beanClass) {
		// Previously we setProxyTargetClass(true) in the constructor, but that has too
		// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
		// aspects. I'm not entirely happy with that as there is no good reason not
		// to advise aspects, except that it causes advice invocation to go through a
		// proxy, and if the aspect implements e.g the Ordered interface it will be
		// proxied by that interface and fail at runtime as the advice method is not
		// defined on the interface. We could potentially relax the restriction about
		// not advising aspects in the future.
		return (super.isInfrastructureClass(beanClass) ||
				(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
	}

shouldSkip() 是否跳过创建

	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
         // 获取候选的增强器
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}	

> 获取全部的增强器

继续回到wrapIfNecessary()中,接下来会获取增强器,getAdvicesAndAdvisorsForBean()获取指定bean的增强方法一定是包含两个步骤的:

  1. 获取所有的增强,通过findCandidateAdvisors()
  2. 寻找所有增强中适用于该bean的增强并应用,通过findAdvisorsThatCanApply()
	// 获取当前Bean的所有增强器
	@Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        // 获取增强方法
        List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
        // 获取到了则返回,获取不到返回null
        return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
    }
     
    // 获取到能在这个目标方法中匹配的增强器
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 1)找到所有的增强器
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        // 2)从所有增强里面获取到能在bean使用的增强器
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        // 3.扩展方法,留个子类实现
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            // 4.对符合条件的Advisor进行排序
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }
a> findCandidateAdvisors() 获取全部增强器
  1. 通过调用父类方法,来解析通过XML配置的AOP
  2. 解析通过注解方式设置的AOP
  3. 将所有的封装成增强器返回
@Override
protected List<Advisor> findCandidateAdvisors() {
   // 1)通过父类,加载对XML配置的AOP
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
      // 2) 解析注解方式配置的AOP
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}
b> buildAspectJAdvisors() 筛选AOP切面类

【方法功能】:既然要筛选切面类,那肯定要遍历项目,筛选出全部标记@Aspect的切面类

上面方法中,会分别解析通过XML和注解配置的AOP,这里只介绍第2种,因为现在的开发更多的使用注解配置

那么就详细看一下buildAspectJAdvisors(),该方法的整体逻辑为:

  1. 第一次获取,不存在增强器缓存的情况
    1. 获取所有在beanFactory中注册的beanName
    2. 遍历所有的beanName,并找出声明@Aspect注解的类
      1. 如果是切面类是单例,则获取到该单例bean中的所有增强方法,然后存入缓存
      2. 其它情况,把当前BeanFactory和切面bean封装为一个多例类型的Factory,存入缓存
  2. 不是第一次获取,存在增强器缓存的情况
    1. 执行到这里,代表缓存中是存在的
    2. 首先从切面缓存中直接获取增强器,代表是一个单例的切面类
    3. 获取不到,则可能是多例,然后对应的factory,然后获取增强类
public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;
  
   // 1.尝试从缓存中获取aspectNames,若没有则手动获取
   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         // 加锁以后Double Check
         if (aspectNames == null) {
            // 返回结果
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            // 1.获取所有的beanName
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            // 2.遍历
            for (String beanName : beanNames) {
               // 不合法的bean则略过, 由子类重写方法定义规则
               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.
               // 获取对应的bean类型
               Class<?> beanType = this.beanFactory.getType(beanName, false);
               if (beanType == null) {
                  continue;
               }
               // 如果该bean存在@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  // 把切面类封装成一个元数据类, 包含bean的树形
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  // 判断@Aspect注解中标注的是否为singleton类型,默认的切面类都是singleton类型
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     // ---------找到增强类中的增强方法, 也就是那些标记 @Before @After 这些注解的方法---------
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     // 如果切面类是singleton类型,则将解析得到的Advisor进行缓存
                     if (this.beanFactory.isSingleton(beanName)) {
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        // 如果不是单例,则将factory放到缓存,以便再次获取时可以通过factory来解析
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     // 如果@Aspect注解标注的beanName的Bean是单例,但切面实例化模型不是单例,则抛异常
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     // 将当前BeanFactory和切面bean封装为一个多例类型的Factory,同时对当前bean和factory进行缓存
                     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<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      // 根据aspectName从缓存中获取Advisor集合
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         // 缓存获取到了,返回结果
         advisors.addAll(cachedAdvisors);
      }
      else {
         // 如果不存在于advisorsCache缓存,则代表存在于aspectFactoryCache中,可能是多例的情况,这时候不能bean,而要存beanFactory
         // 从aspectFactoryCache中拿到缓存的factory,然后解析出Advisor,添加到结果中
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}
c> getAdvisors() 解析切面类中的增强方法

【方法功能】:上面在buildAspectJAdvisors()已经晒出出所有的AOP切面类了,然后就是遍历这些类,通过该方法,筛选里面的切面方法

  1. 获取切面类所有标注了AOP注解的方法
  2. 遍历处理方法
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
   // 1.获取类型
   Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   // 2.获取beanName
   String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   // 3.验证
   validate(aspectClass);

   // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
   // so that it will only instantiate once.
   // 通过上面的英文可以看出将其进行封装,使用装饰器模式,保持每次获取到的都是同一个切面实例
   MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
         new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

   List<Advisor> advisors = new ArrayList<>();
   // 获取所有的没有使用@Pointcut注解标注的方法,然后对其进行遍历
   for (Method method : getAdvisorMethods(aspectClass)) {
      // 判断当前方法是否标注有@Before,@After或@Around等注解,如果标注了,则将其封装为一个Advisor
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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不为空,并且是需要延迟初始化的bean,则在第0位位置添加一个同步实例化增强器(用以保证增强使用之前的实例化)
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
   }

   // Find introduction fields.
   // 判断属性上是否包含有@DeclareParents注解标注的需要新添加的属性,如果有,则将其封装为一个Advisor
   for (Field field : aspectClass.getDeclaredFields()) {
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   return advisors;
}
d> getAdvisor() 普通增强器获取

【方法功能】:前面已经找到了切面类中的所有方法,接下来就是遍历每个方法,层层遍历

上面的getAdvisor()获取到了切面类中的所有方法,然后调用该重载方法,负责对切点方法注解的获取,然后根据注解信息生成增强

@Override
@Nullable
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);
}
e> getPointcut() 切入信息的获取

【方法功能】:负责解析切面注解上的切入点

@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
   // 1.查找并返回给定方法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut)
   AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }

   // 2.使用AspectJExpressionPointcut实例封装获取的信息
   AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
   // 提取得到的注解中的表达式,
   // 例如:@Around("execution(* com.joonwhee.open.aop.*.*(..))"),得到:execution(* com.joonwhee.open.aop.*.*(..))
   ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
   if (this.beanFactory != null) {
      ajexp.setBeanFactory(this.beanFactory);
   }
   return ajexp;
}

在这里插入图片描述

private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
			Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};

@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
   // 从所有的切面注解遍历,找到该方法匹配的注解
   for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
      AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
      if (foundAnnotation != null) {
         return foundAnnotation;
      }
   }
   return null;
}
f> 根据切点信息生成增强器
> 创建增强器包装类并赋初始值

所有的增强都由Advisor的实现类InstantiationModelAwarePointcutAdvisorImpl统一封装的

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;
      // 实例化增强器
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }
}

在这里插入图片描述

> 创建增强器对象
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
   Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
         this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
   return (advice != null ? advice : EMPTY_ADVICE);
}

通过下面方法中的switch可以看到,Spring会根据不同的注解生成不同的增强器

@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);

   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;

   // 根据不同的类创建
   switch (aspectJAnnotation.getAnnotationType()) {
      case AtPointcut:
         if (logger.isDebugEnabled()) {
            logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
         }
         return null;
      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;
      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);
   }
   springAdvice.calculateArgumentBindings();

   return springAdvice;
}

> 筛选该bean可以使用的增强器

a> findAdvisorsThatCanApply()

【方法描述】:遍历全部增强器,依次判断该bean可否应用

继续回到上面的方法中wrapIfNecessary() -> getAdvicesAndAdvisorsForBean() -> findEligibleAdvisors()中,当我们获取了全部的增强以后,这个肯定需要缓存起来的,然后创建bean的时候,需要筛选出该bean可以使用的增强器

	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		// 空的话直接返回
         if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
         // 首先处理引介增强(@DeclareParents)用的比较少可以忽略
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
         // 遍历所有增强器
         for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
             // 判断是否可以应用
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
b> canApply() 判断该bean可否应用增强器
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   // 判断是否上面提到的引介增强,用的比较少
   if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
   }
   // 通常我们的Advisor都是PointcutAdvisor类型
   else if (advisor instanceof PointcutAdvisor) {
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
   }
   else {
      // It doesn't have a pointcut so we assume it applies.
      return true;
   }
}



这里面就是负责把切入点和方法进行匹配

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   Assert.notNull(pc, "Pointcut must not be null");
   // 判断目标bean是否与增强器上面的切点表达式是否匹配
   // 也就是判断 @Pointcut(value = "execution(public int com.h3c.aop.bean.*.*(..))") 这个和目前bean是否匹配
   if (!pc.getClassFilter().matches(targetClass)) {
      return false;
   }

   // 判断如果当前Advisor所指代的方法的切点表达式如果是对任意方法都放行,则直接返回
   MethodMatcher methodMatcher = pc.getMethodMatcher();
   if (methodMatcher == MethodMatcher.TRUE) {
      // No need to iterate the methods if we're matching any method anyway...
      return true;
   }

   IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
   if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
      introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
   }

   // 获取目标类的所有接口
   Set<Class<?>> classes = new LinkedHashSet<>();
   if (!Proxy.isProxyClass(targetClass)) {
      classes.add(ClassUtils.getUserClass(targetClass));
   }
   classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

   // 遍历目标类上的接口方法
   for (Class<?> clazz : classes) {
      // 
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      for (Method method : methods) {
         // 使用matches判断能否作用于该方法上
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
        }
      }
   }

   return false;
}

3.执行逻辑图

上面介绍了如何获取增强器,那么在通过下面的图回顾一下:

在这里插入图片描述

三、根据增强器创建代理

1.Spring代理介绍

上面已经获取到了其增强器,然后继续回到wrapIfNecessary(),接下来就是开始创建代理了,那么在看源码之前先把代理的知识聊一下

如果忘了最基础的如何创建代理请阅读《GoF设计模式》 之No.11代理模式》

那么接下来说一下Spring框架,Spring作为一个优秀的框架,提供了多种应用层面上代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory

注意:此处这里指的是Spring提供的应用层得方式,并不是指的底层实现方式。底层实现方式现在只有业界都熟悉的两种:JDK动态代理和CGLIB代理~

  • ProxyFactoryBean是将我们的AOP和IOC融合起来,
  • ProxyFactory则是只能通过代码硬编码进行编写 一般都是给spring自己使用。
  • AspectJ是目前大家最常用的集成AspectJSpring
    在这里插入图片描述

涉及的关键类说明
ProxyConfig:为上面三个类提供配置属性
AdvisedSupport:继承ProxyConfig,实现了Advised。封装了对通知(Advise)和通知器(Advisor)的操作
ProxyCreatorSupport:继承AdvisedSupport,其帮助子类(上面三个类)创建JDK或者cglib的代理对象

1) ProxyFactoryBean

使用Spring提供的类org.springframework.aop.framework.ProxyFactoryBean是创建AOP的最基本的方式,是比较麻烦的,需要实现特定的接口,并进行一些较为复杂的配置。

它是将Aop和IOC融合起来,所以它肯定是个Bean,然后我们可以自定义我们的代理实现逻辑,最终交给Spring容器管理即可。

public class ProxyFactoryBean extends ProxyCreatorSupport
      implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {

【写个例子】

@Configuration
public class ProxyConfig {

    // 目标类
    @Bean
    public HelloService helloService() {
        return new HelloService();
    }

    // 增强类
    @Bean
    public LogMethodBeforeAdvice logMethodBeforeAdvice() {
        return new LogMethodBeforeAdvice();
    }

    // 创建一个代理,注入IOC,从这里可以看到ProxyFactoryBean会与IOC融合起来
    @Bean
    public ProxyFactoryBean proxyFactoryBean(HelloService helloService) {
        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
        // 设置目标对象
        proxyFactoryBean.setTarget(helloService);
        // 设置需要被代理的接口
        proxyFactoryBean.setInterfaces(HelloInterface.class);
        // 需要植入进目标对象的bean列表 此处需要注意:这些bean必须实现类 org.aopalliance.intercept.MethodInterceptor或 org.springframework.aop.Advisor的bean ,配置中的顺序对应调用的顺序
        proxyFactoryBean.setInterceptorNames("logMethodBeforeAdvice");
        return proxyFactoryBean;
    }


    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProxyConfig.class);
        HelloInterface helloInterface = (HelloInterface) context.getBean("proxyFactoryBean");
        helloInterface.hello();
    }

}

interface HelloInterface {
    void hello();
}

class HelloService implements HelloInterface {

    @Override
    public void hello() {
        System.out.println("执行hello()-------");
    }
}

class LogMethodBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("before-----------------");
    }
}

2) ProxyFactory

它和Spring容器没啥关系,可议直接创建代理来使用:

public static void main(String[] args) {
    ProxyFactory proxyFactory = new ProxyFactory(new HelloService());
    // 添加两个Advise,一个匿名内部类表示
    proxyFactory.addAdvice((AfterReturningAdvice) (returnValue, method, args1, target) ->
            System.out.println("AfterReturningAdvice method=" + method.getName()));
    proxyFactory.addAdvice(new LogMethodBeforeAdvice());

    HelloInterface proxy = (HelloInterface) proxyFactory.getProxy();
    proxy.hello();
}


// 输出
before-----------------
执行hello()-------
AfterReturningAdvice method=hello 

很显然它代理的Bean都是new出来的,所以比如HelloServiceImpl就不能和Spring IoC很好的结合了,所以一般都是Spring内部去使用。

public class ProxyFactory extends ProxyCreatorSupport {
	// 它提供了丰富的构造函数~~~
	public ProxyFactory() {
	}
	public ProxyFactory(Object target) {
		setTarget(target);
		setInterfaces(ClassUtils.getAllInterfaces(target));
	}
	public ProxyFactory(Class<?>... proxyInterfaces) {
		setInterfaces(proxyInterfaces);
	}
	public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
		addInterface(proxyInterface);
		addAdvice(interceptor);
	}
	public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
		addInterface(proxyInterface);
		setTargetSource(targetSource);
	}
	
	// 创建代理的语句:调用父类ProxyCreatorSupport#createAopProxy 此处就不用再解释了
	public Object getProxy() {
		return createAopProxy().getProxy();
	}
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

	// 主义这是个静态方法,可以一步到位,代理指定的接口
	public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
		return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
	}
	public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
		return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
	}
	// 注意:若调用此方法生成代理,就直接使用的是CGLIB的方式的
	public static Object getProxy(TargetSource targetSource) {
		if (targetSource.getTargetClass() == null) {
			throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
		}
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTargetSource(targetSource);
		proxyFactory.setProxyTargetClass(true);
		return proxyFactory.getProxy();
	}
}

3) AspectJProxyFactory

在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并进行一些较为复杂的配置,低版本Spring AOP的配置是被批评最多的地方。Spring听取这方面的批评声音,并下决心彻底改变这一现状。在Spring2.0中,Spring AOP已经焕然一新,你可以使用@AspectJ注解非常容易的定义一个切面,不需要实现任何的接口

AspectJ是目前大家最常用的 起到集成AspectJ和Spring,也就是我们平时长谈的:自动代理模式。它整个代理的过程全部交给Spring内部去完成,无侵入。

我们只需要配置切面、通知、切点表达式就能自动的实现切入的效果,使用起来极其方便,对调用者可以说是非常透明化的。相信这也是为何当下最流行这种方式的原因~

2.源码分析

接下来就是继续看源码了,首先,下面看到的Aop代理源码,采用的ProxyFactory,也就是上面介绍到的第2种,采用硬编码的方式

> createProxy() 创建代理工厂

// AbstractAutoProxyCreator
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
        }
	
        // 获取当前类中的相关属性
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (proxyFactory.isProxyTargetClass()) {
            if (Proxy.isProxyClass(beanClass)) {
                Class[] var6 = beanClass.getInterfaces();
                int var7 = var6.length;

                for(int var8 = 0; var8 < var7; ++var8) {
                    Class<?> ifc = var6[var8];
                    proxyFactory.addInterface(ifc);
                }
            }
        } else if (this.shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        } else {
            this.evaluateProxyInterfaces(beanClass, proxyFactory);
        }
	   
        // 获取所有增强器(通知方法)
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        // 保存到proxyFactory
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        ClassLoader classLoader = this.getProxyClassLoader();
        if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
            classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
        }
        // 获取代理
        return proxyFactory.getProxy(classLoader);
    }

> getProxy 获取代理对象

// ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
   // createAopProxy()调用的父类ProxyCreatorSupport
   return createAopProxy().getProxy(classLoader);
}
> createAopProxy 创建AOP代理
// ProxyCreatorSupport
protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}

public AopProxyFactory getAopProxyFactory() {
	return this.aopProxyFactory;
}

	// DefaultAopProxyFactory
    // 创建代理对象
	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (!NativeDetector.inNativeImage() &&
				(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
              // 普通对象则使用cglib动态代理
			return new ObjenesisCglibAopProxy(config);
		}
		else {
             // 存在接口, 则使用JDK动态代理
			return new JdkDynamicAopProxy(config);
		}
	}
> getProxy()

这里会获取代理对象,如果是采用的JDK动态代理,则执行到JdkDynamicAopProxy

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   // 我们熟悉的代理创建
   return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

如果是采用的Cglib代理,则进入CglibAopProxy

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
   }

   try {
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

      Class<?> proxySuperClass = rootClass;
      if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
         proxySuperClass = rootClass.getSuperclass();
         Class<?>[] additionalInterfaces = rootClass.getInterfaces();
         for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
         }
      }

      // Validate the class, writing log messages as necessary.
      validateClassIfNecessary(proxySuperClass, classLoader);

      // Configure CGLIB Enhancer...
      Enhancer enhancer = createEnhancer();
      if (classLoader != null) {
         enhancer.setClassLoader(classLoader);
         if (classLoader instanceof SmartClassLoader &&
               ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
            enhancer.setUseCache(false);
         }
      }
      enhancer.setSuperclass(proxySuperClass);
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

      Callback[] callbacks = getCallbacks(rootClass);
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
         types[x] = callbacks[x].getClass();
      }
      // fixedInterceptorMap only populated at this point, after getCallbacks call above
      enhancer.setCallbackFilter(new ProxyCallbackFilter(
            this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
      enhancer.setCallbackTypes(types);

      // Generate the proxy class and create a proxy instance.
      return createProxyClassAndInstance(enhancer, callbacks);
   }
   catch (CodeGenerationException | IllegalArgumentException ex) {
      throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
            ": Common causes of this problem include using a final class or a non-visible class",
            ex);
   }
   catch (Throwable ex) {
      // TargetSource.getTarget() failed
      throw new AopConfigException("Unexpected AOP exception", ex);
   }
}

s(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

  Callback[] callbacks = getCallbacks(rootClass);
  Class<?>[] types = new Class<?>[callbacks.length];
  for (int x = 0; x < types.length; x++) {
     types[x] = callbacks[x].getClass();
  }
  // fixedInterceptorMap only populated at this point, after getCallbacks call above
  enhancer.setCallbackFilter(new ProxyCallbackFilter(
        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
  enhancer.setCallbackTypes(types);

  // Generate the proxy class and create a proxy instance.
  return createProxyClassAndInstance(enhancer, callbacks);

}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
“: Common causes of this problem include using a final class or a non-visible class”,
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException(“Unexpected AOP exception”, ex);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为人师表好少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值