Spring5.1源码阅读记录七 - Spring AOP源码分析

在上篇文章中学习了如何实现一个切面,
https://blog.csdn.net/u014533485/article/details/107536422
下面走进代码中看看Spring是如何实现AOP代理功能的。

一、@EnableAspectJAutoProxy注解

想要使用AOP的功能需要在配置类中启用这个注解

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

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;

}

这个注解仅仅引入了AspectJAutoProxyRegistrar.class类,@Import这里就不讲了。也就是说这个类会在register()方法中引入到容器中。

二、AspectJAutoProxyRegistrar类

下面来看这个类的代码,首先这个类是SpringContext中的类。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//将org.springframework.aop.config.internalAutoProxyCreator注入
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
	}

}

首先这个方法registerAspectJAnnotationAutoProxyCreatorIfNecessary()的意思是如果需要
注册AspectJ注释自动ProxyCreator
往这个方法里面走:

	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

很明显,这里就是将AnnotationAwareAspectJAutoProxyCreator.class作为BD注册到容器中!

下面我们看看这个类是什么

三、AspectJAutoProxyRegistrar类

AspectJAutoProxyRegistrar就是属于AOP包下的类了,至此就进入了AOP地盘

package org.springframework.aop.aspectj.annotation;
@SuppressWarnings("serial")
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
	@Nullable
	private List<Pattern> includePatterns;
	@Nullable
	private AspectJAdvisorFactory aspectJAdvisorFactory;
	@Nullable
	private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
	....}

好,到这里先暂停。我们从代码执行角度来看
首先AOP需要工作,就需要生成代理对象,Spring 是如何知道哪些对象需要代理呢?
代码转到生成Bean的createBean()方法,
AbstractAutowireCapableBeanFactory->createBean()

	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		RootBeanDefinition mbdToUse = mbd;

		// Bean初始化之前的通知 InstantiationAwareBeanPostProcessors 查看有没有拓展出来的对象 没有就创建
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
		try {//开始创建实例对象
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}


	}

首先在实例化对象之前会调用BeanPostProcessor的resolveBeforeInstantiation方法,查看有没有拓展的对象

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;

		bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
		if (bean != null) {
			bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
		}
		return bean;
	}

遍历调用Bean实例化前置通知

	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

由于我们开启了AOP注解注入了AnnotationAwareAspectJAutoProxyCreator.class对象
所以此时会调用AbstractAutoProxyCreator->postProcessBeforeInstantiation()方法

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// 创建代理对象
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		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;
	}

这里就比较简单了,意思就是如果满足当前切面的条件就是用代理生成对象,注意这里走的是实例化的前置通知,这里会返回null对象
此时返回到AbstractAutowireCapableBeanFactory->createBean()方法中

try {//开始创建实例对象
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	if (logger.isTraceEnabled()) {
		logger.trace("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

如果其他的实例化前置处理器返回的都是null,进入doCreateBean()进行实例化对象
AbstractAutowireCapableBeanFactory->doCreateBean()

	try {
		//属性赋值
		populateBean(beanName, mbd, instanceWrapper);
		//实例化Bean 并且实例化
		Object object = initializeBean(beanName, exposedObject, mbd);
		exposedObject = object;//实例化Bean
	}

在populateBean方法会调用实例化的后置处理器,这里也没做什么

		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

再往下initializeBean()

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		//前置通知
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		//init方法
		invokeInitMethods(beanName, wrappedBean, mbd);

		//后置通知器 注意此时的Bean已经生成 如果需要代理 就返回代理对象
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

这里会调用Bean的初始化前置通知,初始化对象,以及初始化后置通知,
首先调用Bean的初始化前置通知,这里AOP也没有做什么事
AbstractAutoProxyCreator->postProcessBeforeInitialization()

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
		return bean;
	}

再往下initializeBean()初始化方法,跟AOP也没什么关系,跳过

再往下applyBeanPostProcessorsAfterInitialization()执行后置通知

AbstractAutoProxyCreator->postProcessAfterInitialization()

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

然后调用wrapIfNecessary()判断是否需要代理

	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {

		// Create proxy if we have 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;
	}

如果找到此对象中存在需要代理的方法,那就使用代理返回对象。流程就是差不多这样
具体的代码就不看了。有兴趣的可以一点点点进去查看。

你可能感兴趣的:(SpringMVC)