Spring-AOP源码

1. @EnableAspectJAutoProxy注解

总所周知,使用spring-aop,需要在类上标注@EnableAspectJAutoProxy注解
@EnableAspectJAutoProxy注解使用@Import注解导入了AspectJAutoProxyRegistrar

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy { /** ... **/ }

2. AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar向Spring容器中注入了AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor
也是Spring-AOP中最最核心的类,由该类介入bean的创建流程, 为合适的bean创建代理对象

	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		
		// 向容器中注入AnnotationAwareAspectJAutoProxyCreator
		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);
			}
		}
		**/
	}

3. AnnotationAwareAspectJAutoProxyCreator

继承关系图

在这里插入图片描述

4. AbstractAutoProxyCreator

4.1 postProcessAfterInitialization()

postProcessAfterInitialization()不用多介绍,BeanPostProcessor中定义的后置处理方法

	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

if (this.earlyProxyReferences.remove(cacheKey) != bean)

什么条件下这个判断才能成功呢?

  1. earlyProxyReferences.remove(cacheKey) == null , 也就是说没有被提前创建
  2. 如果被提前创建了earlyProxyReferences.remove(cacheKey)返回的对象一定是 == bean

这样写的好处就是一行代码做了两件事,

  1. 如果没有提前创建, 那么执行wrapIfNecessary方法
  2. 否则从容器中移除

有 Doug Lea 写代码那味了, 如果没有花括号就更像了(手动狗头)

4.2 wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			// 进入`if`分支后, 证明这个`bean`不需要被代理, 直接返回`bean`
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

		if (specificInterceptors != null) {

			this.advisedBeans.put(cacheKey, Boolean.TRUE);

			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;
	}
  1. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))

isInfrastructureClass(bean.getClass() 该类是下面任一的话返回true

  1. Advice
  2. Pointcut
  3. Advisor
  4. AopInfrastructureBean

因为这些类都是用于辅助创建代理对象的,不应该也不需要被代理

shouldSkip(bean.getClass(), beanName)
其实这里子类重新了该方法 AspectJAwareAdvisorAutoProxyCreator#shouldSkip
还是在判断当前类是否是Aspect,用于兼容xml使用beanName的方式配置aspect,没有必要深究

  1. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)

核心方法,找到可以为当前类使用的advisor
子类重写了该方法,具体会调用到AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
—> 进入5跟踪源码

5. AbstractAdvisorAutoProxyCreator

5.1 getAdvicesAndAdvisorsForBean()
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		// 找到所有可用的 { Advisor }
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);

		// 没有找到, 返回NULL
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}

		// 作为数组返回
		return advisors.toArray();
		
	}
5.2 findEligibleAdvisors()
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 1.1 从Spring容器中获取所有的 { Advisor }
		// 1.2 从Spring容器中获取所有的 { Bean } , 如果 { Bean } 使用了 { @Aspect }注解
		//	   那么将其包装成 { Advisor }
		List<Advisor> candidateAdvisors = findCandidateAdvisors();

		// 2. 找到可以为 { beanClass } 使用的 { Advisor }
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		
		// 忽略
		extendAdvisors(eligibleAdvisors);

		// 3. 按照 { @Order } 和 { @PriorityOrder } 注解对Advisors排序
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}

		return eligibleAdvisors;
	}
  1. List<Advisor> candidateAdvisors = findCandidateAdvisors();

AnnotationAwareAspectJAutoProxyCreator重写了这个方法

PS: AnnotationAwareAspectJAutoProxyCreator也就是使用@EnableAspectJAutoProxy注解导入进Spring容器的类
—> 进入5.3跟踪源码

  1. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

并不是所有的Advisor都是可以为当前bean服务的,在ProxyFactory使用篇有提到过, Advisor需要根据ClassMethod匹配上才被使用
调用findAdvisorsThatCanApply,找到可以被当前Bean使用的Advisor

  1. eligibleAdvisors = sortAdvisors(eligibleAdvisors);

排序,用于支持Advisor上的@Order@PriorityOrdered

  1. 返回Advisors
5.3 AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
	protected List<Advisor> findCandidateAdvisors() {
		
		List<Advisor> advisors = super.findCandidateAdvisors();

		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		
		return advisors;
	}
  1. super.findCandidateAdvisors();

从Spring容器中获取所有类型为Advisor的bean
Spring很多功能都是通过向容器中注册Advisor来实现的, 例如

  1. BeanFactoryCacheOperationSourceAdvisor支持Spring-Cache的,例如@Cacheable, @CacheEvict, @Cacheput
  2. AsyncAnnotationAdvisor
  1. this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

很重要
我们使用@Aspect注解定义的切面,就是在这里被找到并且被包装为Advisor
—> 进入5.4跟踪源码

5.4 BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
	// 简化了一部分代码, 删除了一些比较函件的分支
	public List<Advisor> buildAspectJAdvisors() {
		
		// 1. 结果集合, 用于返回
		List<Advisor> advisors = new ArrayList<>();
		
		// 2. 从Spring容器中获取所有的Bean
		String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
				this.beanFactory, Object.class, true, false);
				
		for (String beanName : beanNames) {
		
			// 3. 判断类上是否有 { @Aspect }注解, 如果有, 返回true
			if (this.advisorFactory.isAspect(beanType)) {
				
				AspectMetadata amd = new AspectMetadata(beanType, beanName);
				
				// 包装成MetadataAwareAspectInstanceFactory, 无需深究
				MetadataAwareAspectInstanceFactory factory =
						new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
				
				// 4. 转换为 { Advisor }
				// 为什么可以转换为多个?
				// 例如类里的有方法包标注了`AspectJ的注解` { @Around / @Before / @After... }
				// 那么就会被转换为多个 { Advisor }
				List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
				
				advisors.addAll(classAdvisors);
			}
		}
		
		// 5. 返回结果
		return advisors;
	}

根据代码分析得到:

  1. 找到Spring容器中所有的bean
  2. 找到被@Aspect标注的类
  3. 根据该类中的方法, 包装成0个或多个Advisor

6. AbstractAutoProxyCreator

6.1 继续分析wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			// 进入`if`分支后, 证明这个`bean`不需要被代理, 直接返回`bean`
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 前面分析了 { specificInterceptors } 是如何得到的
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		
		// 从这里开始继续分析
		if (specificInterceptors != null) {

			this.advisedBeans.put(cacheKey, Boolean.TRUE);

			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;
	}

如果specificInterceptors 为空,那么表示没有为当前bean找到合适的advisor,也就不需要为其创建代理,直接把bean返回

否则
调用AbstractAutoProxyCreator类的createProxy方法

6.2 createProxy
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
								 @Nullable Object[] specificInterceptors, TargetSource targetSource) {
		
		// 忽略
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			// 用于辅助这个方法的: 判断Aop对象真正的class
			/** {@link AutoProxyUtils#determineTargetClass(ConfigurableListableBeanFactory, String)} */
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		// 1. 创建ProxyFactory
		ProxyFactory proxyFactory = new ProxyFactory();

		// 2. 忽略
		proxyFactory.copyFrom(this);
		
		// 3. 忽略: 判断是优先基于类代理还是接口代理
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			} else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		// 4. 将 { specificInterceptors } 转换为 { Advisor[] }
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

		// 5. 赋值给proxyFactory
		proxyFactory.addAdvisors(advisors);

		// 6. 赋值targetSource, 这里的targetSource是 { class:SingletonTargetSource }
		proxyFactory.setTargetSource(targetSource);

		// 7. 扩展点, 默认无
		customizeProxyFactory(proxyFactory);
		
		proxyFactory.setFrozen(this.freezeProxy);

		// 8. 告诉ProxyFactory已经过滤过了, 在创建代理时无需再过滤一次
		// "已经过滤过了"是什么意思? 就是指当前的`advisor`都是适用于当前`bean`的
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		// 9. 创建代理
		return proxyFactory.getProxy(getProxyClassLoader());
	}
  1. 创建proxyFactory
  2. proxyFactory赋值
  3. 使用proxyFactory创建代理对象并且返回

至此Spring-AOP介入对象创建生命周期并且创建代理的流程就已经结束了

具体ProxyFactory是如何创建代理的,可以查看这篇文章

ProxyFactory创建代理源码分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值