Spring源码-AOP(六)-AOP代理的创建

上一篇写了AspectJAutoProxyBeanDefinitionParser的注册,以及相关AOP属性的注册,接下来看下AspectJAutoProxyBeanDefinitionParser的自动注册以及它的层级结构。

Spring源码-AOP(六)-AOP代理的创建

从图中可以看到AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,在之前的IOC章节我们之前描述过,Spring加载该bean后会在实例化前调用postProcessAfterInitialization()方法,而我们对于AOP逻辑的分析也由此开始。

AOP逻辑分析

【AbstractAutoProxyCreator】

talk is cheap, show you the code:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		//根据给定的class和name构建出key,格式:beanClassName_beanName
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			//如果他适合被代理,则需要封装指定bean
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}
protected Object wrapIfNecessary(Object bean, @Nullable String beanName, Object cacheKey) {
	//如果已经处理过就直接返回
	if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	//不需要增强
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	//给定的bean类是否代表一个基础设施类,基础设施类不应代理,活配置了指定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;
}

在以上函数中我们已经看到了代理创建的雏形。当然和别的医院,在开始前先进行一系列的判断,比如是否已经处理过或者是否需要挑错,而真正创建代理的代码是从getAdvicesAndAdvisorsForBean()开始的。

创建代理前主要包括两个步骤,如下:

  • 1、获取增强方法或者增强器
  • 2、根据获取的增强进行代理
    核心逻辑时序图如下:
    Spring源码-AOP(六)-AOP代理的创建 AbstractAutoProxyCreator的postProcessAfterInitialization() 方法执行时序图
    虽然看似很简单,但是每个步骤中都进行了大量的复杂逻辑处理。

AOP设计基础

这里再回顾下Spring-AOP的设计基础

  • 增强(Advice):Advice(也翻作 通知)定义了连接点做什么,为切面增强提供了织入的接口。在 Spring AOP 中,它主要描述 Spring AOP 围绕方法调用而注入的切面行为。Advice 是 AOP 联盟定义的一个接口,具体的接口定义在 org.aopalliance.aop.Advice 中。在 Spring AOP 的实现中,使用了这个统一接口,并通过这个接口,为 AOP 切面增强的注入功能做了更多的细化和扩展,比如前面提到的具体通知类型,如BeforeAdvice、AfterAdvice、ThrowsAdvice等
    Spring源码-AOP(六)-AOP代理的创建
  • 切点:Pointcut(关注点,也称 切点)用于决定 Advice 增强作用于哪个连接点,也就是说通过 Pointcut 来定义需要增强的方法集合,而这些集合的选取可以通过一定的规则来完成,例如:这些需要增强的地方可以由某个正则表达式来进行标识,或根据某个方法名来进行匹配等。
    Spring源码-AOP(六)-AOP代理的创建
  • 通知器:Advisor(通知器)用一个对象将对目标方法的切面增强设计(Advice)和关注点的设计(Pointcut)结合起来
    Spring源码-AOP(六)-AOP代理的创建

原文 

http://sunliangliang.com/2017/09/05/Spring源码-AOP-六-AOP代理的创建/

PS:如果您想和业内技术大牛交流的话,请加qq群(527933790)或者关注微信公众 号(AskHarries),谢谢!

转载请注明原文出处:Harries Blog™ » Spring源码-AOP(六)-AOP代理的创建

赞 (0)

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址