Spring源码解析之-- 事务InfrastructureAdvisorAutoProxyCreator 分析

一、介绍

上一章 Spring源码解析之-- 事务注解 处理流程 分析我们已经 介绍了 事务的 分析过程,这一章,详细对其中的 几个步骤 分析在何时 起作用.

二、InfrastructureAdvisorAutoProxyCreator 分析

2.1 结构

在这里插入图片描述
从层次结构图上,可以看出 InfrastructureAdvisorAutoProxyCreator 继承了 AbstractAutoProxyCreator, 而AbstractAutoProxyCreator 实现了SmartInstantiationAwareBeanPostProcessor 接口, 所以在每一个bean 初始化过程都是会运行 postProcessAfterInitialization 方法

关于 BeanPostProcessor 相关的运行机制 ,可以查看 spring源码解析之—BeanPostProcessor解析

2.1 解析

2.1.1 postProcessBeforeInstantiation

我们知道 在Bean 实例化之前会运行 postProcessBeforeInstantiation,我们先看一下 AbstractAutoProxyCreator.class 里面对应的
postProcessBeforeInstantiation 实现, 这里会先判断一些是否需要代理, 在postProcessAfterInitialization 里面会获取

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        // 主要对 FactoryBean 的前缀加一下"&"
		Object cacheKey = getCacheKey(beanClass, beanName);
        // 判断targetSourcedBeans 是否包含beanName, targetSourcedBeans 里放的是 已经处理好的targetSource
		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
		    // 如果 advisedBeans里面包含 cachekey,返回null, 说明此 beanClass 之前已经被处理过了
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			/** 这里判断beanClass 是否 Advice.class,Pointcut.class,Advisor.class,
			AopInfrastructureBean.class ,如果实现了这些接口,就不需要代理,放入advisedBeans中, value 设置为False
			shouldSkip: 主要就是判断给定的bean名称是否表示"original instance"
			*/
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		/**
		这里是获取自定义的 targetSource,Spring 提供了LazyInitTargetSourceCreator, QuickTargetSourceCreator,
		也可以自定义,获取到targetSource,加入到targetSourcedBeans 里面,创建代理
        AbstractAutoProxyCreator 被很多的类继承, 所以getAdvicesAndAdvisorsForBean 的实现也各不相同
        这里我们 就只AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean 的逻辑
         具体在下面getAdvicesAndAdvisorsForBean  和createProxy 的逻辑下面分析
		**/
		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;
	}

2.1.2 postProcessAfterInitialization

接下来看一下postProcessAfterInitialization 的相关逻辑

	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
		// 主要对 FactoryBean 的前缀加一下"&"
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			//判断是否是否循环依赖
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			    // 对当前bean 进行封装
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

2.1.3 wrapIfNecessary

wrapIfNecessary主要的逻辑是:

  1. 从 targetSourcedBeans 获取, 如果有直接返回
  2. 从 advisedBeans 获取,如果为false, 直接返回,不需要增强
  3. 判断是否是 Advice.class,Pointcut.class,Advisor.class, AopInfrastructureBean.class ,如果实现了这些接口,就不需要增强,直接返回,并放入advisedBeans里面
  4. 获取 适合的 候选增强器
  5. 创建对应的代理并返回
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	     // 如果已经处理过了,直接返回
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//从advisedBeans获取beanName 对应的,是否需要advise, false 就说明不需要封装,直接返回
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		/** 这里判断beanClass 是否 Advice.class,Pointcut.class,Advisor.class,
			AopInfrastructureBean.class ,如果实现了这些接口,就不需要代理,放入advisedBeans中, value 设置为False
			shouldSkip: 主要就是判断给定的bean名称是否表示"original instance"
		*/
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 获取 适合的 候选增强器
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
		    // 首先将cacheKey 放入advisedBeans ,并设置TRUE
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
		    // 对适合的bean 创建 一个AOP 代理,详细代码下面分析
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}
        // 如果上面没有找到适合的 advice,设置为 false
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

2.1.4 getAdvicesAndAdvisorsForBean

	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        //找出适合的 候选增强器
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

2.1.4 findEligibleAdvisors

findEligibleAdvisors 的主要逻辑就是:

  1. 找到所有实现了Advisor接口的候选增强器类
  2. 对所有的候选增强器进行遍历,选出匹配beanClass的
  3. 有一个 hook方法,用于有需要可以自定义实现, 最后进行排序,然后 输出
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	   // 找出所有的实现了Advisor接口的候选增强器类
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 选出匹配的 增强器
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		// 这个是钩子方法,用于用户自定义实现
		extendAdvisors(eligibleAdvisors);
		// 进行排序
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

	protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

2.1.4 findAdvisorBeans

findAdvisorBeans 方法里面的主要逻辑就是 :

  1. 首先判断一下缓存 cachedAdvisorBeanNames 里面是否有数据,有就直接拿来使用
  2. 如果没有,这里主要是调用DefaultListableBeanFactory#getBeanNamesForType 的方法, 根据Type 类型,找到Advisor.class 所有对应的 beanName ,并缓存到 cachedAdvisorBeanNames
  3. 根据获取到的 advisorNames , 遍历对应的 Bean ,然后返回

下面是相关源码解析

public List<Advisor> findAdvisorBeans() {
		// 获取缓存的advisor Bean 的名称列表,如果为null, 
		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			/** 这里是根据type  类型获取所有Advisor 对应的所有的类的beanName, 里面其实是调用的
			DefaultListableBeanFactory#getBeanNamesForType
			**/
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}

		List<Advisor> advisors = new ArrayList<>();
		for (String name : advisorNames) {
		 // isEligibleBean()是提供的一个钩子方法,这里默认返回值都是true
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
					   // 根据beanName 获取对应的Bean,加到advisors 里面
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
						Throwable rootCause = ex.getMostSpecificCause();
						if (rootCause instanceof BeanCurrentlyInCreationException) {
							BeanCreationException bce = (BeanCreationException) rootCause;
							String bceBeanName = bce.getBeanName();
							if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
								if (logger.isTraceEnabled()) {
									logger.trace("Skipping advisor '" + name +
											"' with dependency on currently created bean: " + ex.getMessage());
								}
								// Ignore: indicates a reference back to the bean we're trying to advise.
								// We want to find advisors other than the currently created bean itself.
								continue;
							}
						}
						throw ex;
					}
				}
			}
		}
		return advisors;
	}

2.1.5 AopUtils#findAdvisorsThatCanApply

findAdvisorsThatCanApply 这里 主要逻辑为:

  1. 判断候增强器是否为空,为空直接返回

2.对候选增强器 进行遍历, 首先是处理的 引介增强器IntroductionAdvisor 的,并判断是否匹配
4. 再次遍历,先排查已经处理过的 IntroductionAdvisor 类型后 ,判断是否匹配

	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	    // 如果候选增强器为空,直接返回
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		// 进行遍历,如果Advisor是IntroductionAdvisor 的实例,并且匹配,加到list 里面
		for (Advisor candidate : candidateAdvisors) {
		    // 首先处理 引介 增强型
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		// 再次处理,先排查已经处理过的IntroductionAdvisor类型
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}

2.1.6 AbstractAutoProxyCreator#createProxy

createProxy的主要流程如下:

  1. 首先判断一下beanFactory 是否是 ConfigurableListableBeanFactory 类型, 暴露targetclass, 主要就是对BeanDefinition 增加一个属性
  2. 创建代理工厂,复制一些属性,判断是用jdk动态代理,还是 CLLIB 代理
  3. 将advice 封装成 advisors ,然后根据 上面的 具体的哪种代理,创建AopProxy ,然后 获取具体的代理对象
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
        // 如果beanFactory 是 ConfigurableListableBeanFactory 类型
        // 这里暴露targetclass, 主要就是对BeanDefinition 增加一个属性
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}
        // 创建代理工厂
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);
        /** proxyTargetClass 默认是 false, 也就是说默认是 jdk 代理
        这里判断一下,是否需要设为cglib 代理
        目标对象实现了接口 – 使用CGLIB代理机制
        目标对象没有接口(只有实现类) – 使用CGLIB代理机制
         **/
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
        // 这里是获取所有的advisors ,将 advice封装成 advisors
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);
        //用来配置是否允许修改代理的配置,默认为false
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
         /** 获取AopProxy, 这里会根据 上面的是jdk 代理还是CGLIb代理,返回对应的
         JdkDynamicAopProxy 或者 ObjenesisCglibAopProxy ,  然后再获取具体的代理对象
         **/
		return proxyFactory.getProxy(getProxyClassLoader());
	}
	
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

在这里插入图片描述

evaluateProxyInterfaces的主要逻辑如下:

  1. 获取beanclass 所有的 interface
  2. 对所有的interface 继续判断,是否是 回调接口,或者一些内部语言接口 ,并且需要 有至少一个方法
  3. 如果适合jdk 代理,那就所有的接口加入,不然就使用CGLIB代理
	protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
		boolean hasReasonableProxyInterface = false;
		for (Class<?> ifc : targetInterfaces) {
			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
					ifc.getMethods().length > 0) {
				hasReasonableProxyInterface = true;
				break;
			}
		}
		if (hasReasonableProxyInterface) {
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
			for (Class<?> ifc : targetInterfaces) {
			  // 添加代理接口
				proxyFactory.addInterface(ifc);
			}
		}
		else {
		   // 如果没有找到,就是用 CGLib代理
			proxyFactory.setProxyTargetClass(true);
		}
	}

三、小结

本章详细分析了InfrastructureAdvisorAutoProxyCreator 的层次结构,以及一些事务功能的初始化工作.

支付宝微信
支付宝微信
如果有帮助记得打赏哦特别需要您的打赏哦
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一直打铁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值