我的架構夢:(七)Spring框架中的AOP源碼分析

一、代理對象創建

1、AOP基礎用例準備

Bean定義

@Component
public class RiemannBean {
	public void print(){
		System.out.println("RiemannBean print...");
	} 
}

Aspect定義

@Component
@Aspect
public class RiemannAspect {
	@Pointcut("execution(* com.riemann.*.*(..))") 
	public void pointcut(){
	}
	@Before("pointcut()") 
	public void before() {
		System.out.println("before method ..."); }
	}
}

測試用例

/**
 *  Ioc 容器源碼分析基礎案例
 */
@Test
public void testAOP() {
	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
	RiemannBean riemannBean = applicationContext.getBean(RiemannBean.class);
	riemannBean.print();
}

2、時機點分析

在這裏插入圖片描述

我們發現在 getBean 之前,RiemannBean對象已經產生(即在第一行初始化代碼中完成),而且該對象是一個代理對象(Cglib代理對象),我們斷定,容器初始化過程中目標Ban已經完成了代理,返回了代理對象。

3、代理對象創建流程

3.1 AbstractAutowireCapableBeanFactory#createBean#doCreateBean

在這裏插入圖片描述
3.2 AbstractAutowireCapableBeanFactory#initializeBean

在這裏插入圖片描述

/**
 * 初始化Bean
 * 包括Bean後置處理器初始化
 * Bean的一些初始化方法的執行init-method
 * Bean的實現的生命週期相關接口的屬性注入
 */
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	// 執行所有的AwareMethods
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		// before
		// 執行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前 的處理器方法
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		// 觸發初始化方法調用
		// 這裏就開始執行afterPropertiesSet(實現了InitializingBean接口)方法和initMethod
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
		// after
		// 整個Bean初始化完成,執行後置處理器方法。
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

3.3 AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

在這裏插入圖片描述

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	// 循環執行後置處理器
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

3.4 創建代理對象的後置處理器AbstractAutoProxyCreator#postProcessAfterInitialization

在這裏插入圖片描述

在這裏插入圖片描述

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		/**
		 * 檢查下該類是否已經暴露過了(可能已經創建過了,比如A依賴B時,創建A時候,就會去創建B)
		 * 當真正需要創建B時,就沒必要再代理一次已經代理過的對象,避免重複創建。
		 */
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

3.5 創建代理對象的後置處理器AbstractAutoProxyCreator#wrapIfNecessary

在這裏插入圖片描述

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// targetSourcedBeans包含,說明前面創建過
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	// 得到所有候選Advisor,對Advisors和bean的方法雙層遍歷匹配,最終得到一個List<Advisor>,即specificInterceptors
	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;
}

3.6 AbstractAutoProxyCreator#createProxy

/**
 * 爲指定 bean 創建代理對象
 */
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 proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);

	// 根據一些情況判斷是否要設置proxyTargetClass=true
	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	// 把指定和通用攔截對象合併, 並都適配成Advisor
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	// 設置參數
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}

	// 上面準備做完就開始創建代理
	return proxyFactory.getProxy(getProxyClassLoader());
}

3.7 接着跟進到ProxyFactory

public class ProxyFactory extends ProxyCreatorSupport {
	public Object getProxy(@Nullable ClassLoader classLoader) {
		/**
		 * 用ProxyFactory創建AopProxy, 然後用AopProxy創建Proxy, 所以這裏重要的是看獲取的
		 * AopProxy對象是什麼,然後進去看怎麼創建動態代理, 提供了兩種:jdk proxy, cglib
		 */
		return createAopProxy().getProxy(classLoader);
	}
}
public class ProxyCreatorSupport extends AdvisedSupport {

	private AopProxyFactory aopProxyFactory;

	public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
	
	public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
	
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// 先獲取創建AopProxy的工廠, 再由此創建AopProxy
		return getAopProxyFactory().createAopProxy(this);
	}

	private void activate() {
		this.active = true;
		for (AdvisedSupportListener listener : this.listeners) {
			listener.activated(this);
		}
	}
	...
}

流程就是用AopProxyFactory創建AopProxy, 再用AopProxy創建代理對象,這裏的AopProxyFactory默認是DefaultAopProxyFactory,看它的createAopProxy方法。

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (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);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

	/**
	 * Determine whether the supplied {@link AdvisedSupport} has only the
	 * {@link org.springframework.aop.SpringProxy} interface specified
	 * (or no proxy interfaces specified at all).
	 */
	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		Class<?>[] ifcs = config.getProxiedInterfaces();
		return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
	}

}

這裏決定創建代理對象是用JDK Proxy,還是用 Cglib 了,最簡單的從使用方面來說:設置 proxyTargetClass=true強制使用Cglib 代理,什麼參數都不設並且對象類實現了接口則默認用JDK 代 理,如果沒有實現接口則也必須用Cglib

3.8 ProxyFactory#getProxyCglibAopProxy#getProxy

@Override
public Object getProxy() {
	return getProxy(null);
}

@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 (ClassUtils.isCglibProxyClass(rootClass)) {
			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...
		// 配置 Cglib 增強
		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 ClassLoaderAwareUndeclaredThrowableStrategy(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);
	}
}

在這裏插入圖片描述
到此,代理對象創建流程我們就分析完了。

二、Spring聲明式事務控制

聲明式事務很方便,尤其純註解模式,僅僅幾個註解就能控制事務了。

思考:這些註解都做了什麼?好神奇! @EnableTransactionManagement @Transactional

1、@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

@EnableTransactionManagement 註解使用 @Import 標籤引入了 TransactionManagementConfigurationSelector類,這個類又向容器中導入了兩個重要的組件:

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

在這裏插入圖片描述

2、加載事務控制組件

2.1 AutoProxyRegistrar

AutoProxyRegistrar 類的 registerBeanDefinitions 方法中又註冊了一個組件。

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		for (String annType : annTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			if (candidate == null) {
				continue;
			}
			Object mode = candidate.get("mode");
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
				if (mode == AdviceMode.PROXY) {
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					if ((Boolean) proxyTargetClass) {
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
						return;
					}
				}
			}
		}
		if (!candidateFound && logger.isInfoEnabled()) {
			String name = getClass().getSimpleName();
			logger.info(String.format("%s was imported but no annotations were found " +
					"having both 'mode' and 'proxyTargetClass' attributes of type " +
					"AdviceMode and boolean respectively. This means that auto proxy " +
					"creator registration and configuration may not have occurred as " +
					"intended, and components may not be proxied as expected. Check to " +
					"ensure that %s has been @Import'ed on the same class where these " +
					"annotations are declared; otherwise remove the import of %s " +
					"altogether.", name, name, name));
		}
	}

}

在這裏插入圖片描述

進入 AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法

在這裏插入圖片描述

發現最終,註冊了一個叫做 InfrastructureAdvisorAutoProxyCreatorBean,而這個類是 AbstractAutoProxyCreator 的子類,實現了 SmartInstantiationAwareBeanPostProcessor 接口。

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

繼承體系結構圖如下:

在這裏插入圖片描述
它實現了SmartInstantiationAwareBeanPostProcessor,說明這是一個後置處理器,而且跟 spring AOP 開啓@EnableAspectJAutoProxy 時註冊的 AnnotationAwareAspectJProxyCreator實現的是同一個接口,所以說,聲明式事務是 springAOP 思想的一種應用。

2.2 ProxyTransactionManagementConfiguration 組件

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		// 事務增強器
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 向事務增強器中注入 屬性解析器 transactionAttributeSource
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		// 向事務增強器中注入 事務攔截器 transactionInterceptor
		advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	// 屬性解析器 transactionAttributeSource
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	// 事務攔截器 transactionInterceptor
	public TransactionInterceptor transactionInterceptor() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

ProxyTransactionManagementConfiguration是一個容器配置類,註冊了一個組件 transactionAdvisor,稱爲事務增強器,然後在這個事務增強器中又注入了兩個屬性: transactionAttributeSource,即屬性解析器transactionAttributeSource 和 事務攔截器 transactionInterceptor

2.3 屬性解析器 AnnotationTransactionAttributeSource 部分源碼如下:

public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
		implements Serializable {

	private static final boolean jta12Present;

	private static final boolean ejb3Present;

	static {
		ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();
		jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader);
		ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader);
	}

	private final boolean publicMethodsOnly;
	
	// 註解解析器集合
	private final Set<TransactionAnnotationParser> annotationParsers;
	
	...
}

屬性解析器有一個成員變量是annotationParsers,是一個集合,可以添加多種註解解析器 (TransactionAnnotationParser),我們關注 Spring 的註解解析器,部分源碼如下:

在這裏插入圖片描述

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

	@Override
	@Nullable
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}

	public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
		return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
	}

	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());
		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));

		List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}


	@Override
	public boolean equals(Object other) {
		return (this == other || other instanceof SpringTransactionAnnotationParser);
	}

	@Override
	public int hashCode() {
		return SpringTransactionAnnotationParser.class.hashCode();
	}

}

在這裏插入圖片描述
屬性解析器的作用之一就是用來解析@Transactional註解

2.4 TransactionInterceptor 事務攔截器 部分源碼如下:

在這裏插入圖片描述

上述組件如何關聯起來的?

  • 事務攔截器實現了MethodInterceptor接口,追溯一下上面提到的 InfrastructureAdvisorAutoProxyCreator後置處理器,它會在代理對象執行目標方法的時候 獲取其攔截器鏈,而攔截器鏈就是這個TransactionInterceptor,這就把這兩個組件聯繫起來。
  • 構造方法傳入PlatformTransactionManager(事務管理器)、TransactionAttributeSource(屬性解析器),但是追溯一下上面貼的ProxyTransactionManagementConfiguration的源碼, 在註冊事務攔截器的時候並沒有調用這個帶參構造方法,而是調用的無參構造方法,然後再 調用set方法注入這兩個屬性,效果一樣。

invokeWithinTransaction 方法,部分源碼如下(關注1、2、3、4 標註處)

在這裏插入圖片描述

AOP源碼分析中的代理對象創建以及Spring聲明式事務控制分析到此告一段落,希望文章對你有些幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章