AOP源代码分析


AOP源代码分析

阅读spring的源代码,来查看spring是如何实现AOP增强的

被AOP代理的Bean对象创建过程

在普通bean的加载流程中,如果一个bean是被AOP拦截增强后doCreateBean方法返回的是CGLib动态代理类生成的对象

  • CGLib动态代理对象

doCreateBean

  • 未被AOP增强的对象

doCreateBean

可以得出结论,spring是在bean的创建时期对bean就进行了增强。我们继续往下看

if (instanceWrapper == null) {
  instanceWrapper = createBeanInstance(beanName, mbd, args);
}

在这里创建出bean对象,继续向下看代码,initializeBean这个方法对bean创建后进行了后置操作后返回的是CGLib动态代理后的对象。跟踪方法到了applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),在这里完成了动态代理。

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)方法分析这个方法主要是执行BeanPostProcessor.postProcessAfterInitialization这个方法,其中在初始化时候会执行AnnotationAwareAspectJAutoProxyCreator这个实现类

  • 类图

8ViR1A.png

从类图可以看到这个类的postProcessAfterInitialization方法是父类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) {
	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.
	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;
}

wrapIfNecessary方法首先返回了目标对象需要增强的拦截器
8VkGRJ.png
如果目标对象有需要增强的拦截器,执行创建proxy的程序

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 = new ProxyFactory();
	proxyFactory.copyFrom(this);

	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	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());
}
  1. 暴露目标的原始属性
  2. 创建ProxyFactory对象
  3. 获取到目标对象的Advisor
  4. 最后使用proxyFactory.getProxy来进行一个初始化工作,底层调用JDK的动态代理或者是CGLib的动态代理

AOP的底层原理

通过JDK或者CGLib生成不同的AopProxy对象,从而构造了不同的回调方法来对拦截器链进行调用。
拦截器的调用调用的过程都是在ReflectiveMethodInvocation中通过proceed方法实现的。在proceed方法中,会逐个运行拦截器的拦截方法。在运行拦截器的拦截方法之前,需要对代理方法完成一个匹配判断,通过这个匹配判断来决定拦截器是否满足切面增强的要求。如果方法符合要求进行通知增强,依次调用拦截器链上的拦截器依次直到最后一个拦截器调用完毕执行目标方法

总结

spring实现AOP的方式是在bean初始化过程中,一个BeanPostProcessor接口的postProcessAfterInitialization方法对bean进行一个处理。AbstractAutoProxyCreator是实际进行aop拦截增强的类,执行步骤依次是
1.暴露目标类的原始属性
2. 创建ProxyFactory对象
3. 获取到目标对象的Advisor
4. 使用JDK或CGLib生成代理对象


  TOC