1、Springboot之事务&aop的核心功能源码分析

依赖spring-boot-starter-web内部嵌套依赖spring-aop默认提供核心类之后置处理器InfrastructureAdvisorAutoProxyCreator,意味着不管 AOP 异或 事务Transaction 都存在发挥效用的可能性【InfrastructureAdvisorAutoProxyCreator -> AbstractAdvisorAutoProxyCreator -> AbstractAutoProxyCreator】,如果需要 AOP 异或 事务必须生效则需要显示添加依赖spring-boot-starter-aop、spring-tx。

后置处理器InfrastructureAdvisorAutoProxyCreator【AbstractAutoProxyCreator】的必要性:尝试为每个bean创建Cglib代理。

public abstract class AbstractAutoProxyCreator{
		protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
				...
				//通过当前bean获取Advisor and Advice
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
				if (specificInterceptors != DO_NOT_PROXY) {
					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;
		}
		protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,TargetSource targetSource) {
				List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
				if (advisors.isEmpty()) {
					return DO_NOT_PROXY;
				}
				return advisors.toArray();
		}

		protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
				// 从IOC容器中候选Advisor
				List<Advisor> candidateAdvisors = findCandidateAdvisors();
				// 从众多候选Advisor 选择适合当前bean的Advisor
				List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
				extendAdvisors(eligibleAdvisors);
				if (!eligibleAdvisors.isEmpty()) {
					eligibleAdvisors = sortAdvisors(eligibleAdvisors);
				}
				return eligibleAdvisors;
		}
}

bean可以被代理的前提是:当前IOC容器存在切面类Advisor,并且该Advisor的切点Pointcut作用范围包含当前bean。如果是事务则当前bean的类名或者内部方法存在@Transactional。

1.切面类Advisor的提前初始化

SpringBoot自动装配引入AOP 或者 事务Transaction 相关的切面类Advisor,例如:

  1. 事务引入的切面类Advisor:BeanFactoryTransactionAttributeSourceAdvisor;通知Advice:TransactionInterceptor;切点Pointcut:TransactionAttributeSourcePointcut。
  2. Aop引入的切面类Advisor:InstantiationModelAwarePointcutAdvisorImpl;切点Pointcut:AspectJExpressionPointcut;通知Advice:前置通知、环绕通知、后置通知…。

1.1.事务Transaction之切面类Advisor

通常SpringBoot操作数据库需要依赖:

// 数据库厂商提供操作数据库的api
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
//SpringBoot提供操作数据库的api,例如jdbcTemplate。是对操作数据库的api再次封装
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
  <scope>compile</scope>
</dependency>
//mybatis 对 spring-boot-starter-jdbc 再次封装
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>

spring-boot-starter-jdbc内部封装了spring-jdbc,spring-jdbc 内部封装了spring-tx,spring-tx 提供事务操作的拦截器TransactionInterceptor。该拦截器拦截@Transactional注解,完成所在类的代理。

项目中只要存在依赖spring-tx,则必定触发TransactionAutoConfiguration、TransactionInterceptor类加载。

自动装配类TransactionAutoConfiguration存在于spring-boot-autoconfigure包中,并且该候选类生效的前提是存在依赖spring-tx。

public class ProxyTransactionManagementConfiguration {
	//TRANSACTION_ADVISOR_BEAN_NAME:org.springframework.transaction.config.internalTransactionAdvisor
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
			BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
			advisor.setTransactionAttributeSource(transactionAttributeSource());
			advisor.setAdvice(transactionInterceptor());
			...
			return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor(
			TransactionAttributeSource transactionAttributeSource) {
			TransactionInterceptor interceptor = new TransactionInterceptor();
			interceptor.setTransactionAttributeSource(transactionAttributeSource);
			if (this.txManager != null) {
				interceptor.setTransactionManager(this.txManager);
			}
			return interceptor;
	}
		
}
  1. 事务中切面类Advisor默认为BeanFactoryTransactionAttributeSourceAdvisor,通知Advice默认为TransactionInterceptor
  2. 核心类ProxyTransactionManagementConfiguration是通过类TransactionAutoConfiguration内部注解@EnableTransactionManagement引入的。
  3. 注解@Role是BeanFactoryTransactionAttributeSourceAdvisor满足 InfrastructureAdvisorAutoProxyCreator#isEligibleBean 逻辑的关键。

1.2、Aop之切面类Advisor的初始化

advisorNames:注解@Aspect对应的类。
Advisor:InstantiationModelAwarePointcutAdvisorImpl。

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// 调用抽象类对应的方法,事务获取切面类Advisor方式
		List<Advisor> advisors = super.findCandidateAdvisors();
		if (this.aspectJAdvisorsBuilder != null) {
			//Aop获取切面类Advisor的方式
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
}
public class BeanFactoryAspectJAdvisorsBuilder {
	public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;
		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new ArrayList<>();
					aspectNames = new ArrayList<>();
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {
						if (!isEligibleBean(beanName)) {
							continue;
						}
						...
						if (this.advisorFactory.isAspect(beanType)) {
							aspectNames.add(beanName);
							...
							advisors.addAll(classAdvisors);
						}
					}
					this.aspectBeanNames = aspectNames;
					return advisors;
				}
			}
		}
		...
		return advisors;
	}
}

类似于Transaction,AnnotationAwareAspectJAutoProxyCreator同样重写了isEligibleBean方法。
针对Aop其候选切面类Advisor必选满足两个条件:

  1. isEligibleBean ~ 是否有资格进行自动代理。
  2. 当前bean必须存在@Aspect注解。

2、AbstractAutoProxyCreator获取切面类Advisor

该类型的后置处理器其核心功能总结:判断当前bean是否需要代理处理并且返回对应的切面类Advisor。

public abstract class AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor{
	
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		...
		return wrapIfNecessary(bean, beanName, cacheKey);
	}

	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		...
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}
		...
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//#1
		if (specificInterceptors != DO_NOT_PROXY) {
			...//具体代理类生成过程
			return proxy;
		}
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
}

Map集合类型的属性advisedBeans,其元素为不需要的代理的bean。
isInfrastructureClass:表示是否为aop相关的基础设施类。infrastructureClass包含Advice、Pointcut、Advisor、AopInfrastructureBean以及AnnotationAwareAspectJAutoProxyCreator提供的@Aspect等类。这些infrastructureClass均不需要代理处理。

步骤1:当前bean如果需要代理则返回其对应的切面类Advisor。注意此时的Advisor中已经包含其通知advice、切点pointcut等核心类。

2.1、AbstractAdvisorAutoProxyCreator

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
	private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
	
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,TargetSource targetSource) {
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		List<Advisor> candidateAdvisors = findCandidateAdvisors();//#1
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//#2
		...
		return eligibleAdvisors;
	}

	protected List<Advisor> findCandidateAdvisors() {
		return this.advisorRetrievalHelper.findAdvisorBeans();//#2
	}

	private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {
		public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
			super(beanFactory);
		}
		@Override
		protected boolean isEligibleBean(String beanName) {
			return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
		}
	}
}

步骤1分别是Aop、Transaction获取切面类Advisor的核心方法:

  1. Aop:AnnotationAwareAspectJAutoProxyCreator重写了抽象类AbstractAdvisorAutoProxyCreator中方法findCandidateAdvisors获取提前初始化的切面类Advisor。
  2. Transaction :区别于Aop的后置处理器,事务后置处理器之InfrastructureAdvisorAutoProxyCreator通过步骤#2调用AbstractAdvisorAutoProxyCreator类中方法获取提前初始化的切面类Advisor。

3、执行代理逻辑

4、AspectJAwareAdvisorAutoProxyCreator

AspectJAwareAdvisorAutoProxyCreator重写了抽象父类AbstractAutoProxyCreatorshouldSkip方法。

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	for (Advisor advisor : candidateAdvisors) {
		if (advisor instanceof AspectJPointcutAdvisor &&
				((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
			return true;
		}
	}
	return super.shouldSkip(beanClass, beanName);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值