Spring AOP原理之AnnotationAwareAspectJAutoProxyCreator增强目标类生成代理

目录

1. 说明

2. 目标类创建过程

3. 目标类创建之前尝试生成代理

4. 目标类被增强生成代理类

1. 说明

AnnotationAwareAspectJAutoProxyCreator作为InstantiationAwareBeanPostProcessor和BeanPostProcessor子类,在普通组件被创建的时候,在创建之前会调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation尝试创建一个代理类,在组件被创建并属性赋值后,在执行自定义初始化方法的时候会分别执行BeanPostProcessor的postProcessBeforeInitialization方法和postProcessAfterInitialization方法;

所以,就是在需要被代理的目标类在创建的时候,在这些方法中被判断、增强,最后将增强后的代理类放入到IOC容器中,供后续使用;

2. 目标类创建过程

1). 通过配置类,创建IOC容器
2). 注册配置类,调用refresh();刷新容器;
3). 刷新容器过程中,finishBeanFactoryInitialization(beanFactory)会完成到这一步还没有被创建的单实例组件,
    3.1) 遍历获取容器中所有的Bean,依次创建对象getBean(beanName): getBean->doGetBean()->getSingleton()->先从缓存中获取,没有就调用createBean()创建组件;
    3.2) 在createBean()创建bean的过程中
        3.2.1) resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation,希望后置处理器在此能返回一个代理对象;如果能返回代理对象就使用;
        3.2.2) 如果没有创建代理对象,则调用doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例;

在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])创建组件的过程代码如下:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		// 尝试通过BeanPostProcessors给目标类创建一个代理类,这里面是通过InstantiationAwareBeanPostProcessor来实现的
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	if (logger.isDebugEnabled()) {
		logger.debug("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

3. 目标类创建之前尝试生成代理

在真正创建组件之前,Spring会尝试通过BeanPostProcessor(这里指的是InstantiationAwareBeanPostProcessor)创建出代理类,如果创建成功,这直接将创建的代理类注册到IOC容器中,就是createBean()中的resolveBeforeInstantiation()方法;

因为AnnotationAwareAspectJAutoProxyCreator也是InstantiationAwareBeanPostProcessor的子类,所有也会被调用,尝试通过AbstractAutowireCapableBeanFactory的resolveBeforeInstantiation生成代理类,具体实现在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String, RootBeanDefinition)的代码如下: 

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	// 判断是否允许在创建组件对象前解析
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		// 判断容器中是否有InstantiationAwareBeanPostProcessor组件
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				// 调用所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
				// 这里就会调用AnnotationAwareAspectJAutoProxyCreator的父类的postProcessBeforeInstantiation方法
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					//如果创建成功,则调用所有BeanPostProcessor的postProcessAfterInitialization方法
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

其中,AbstractAutoProxyCreator的postProcessBeforeInstantiation的实现如下:

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	Object cacheKey = getCacheKey(beanClass, beanName);
	
	if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
		if (this.advisedBeans.containsKey(cacheKey)) {
			return null;
		}
		/** 
			isInfrastructureClass(beanClass):
			判断是不是aop的基础类,就是Advice,Pointcut,Advisor,AopInfrastructureBean的子类或者被@Aspect标记的类,所以非切面类这里不会跳过,还会继续往下走,所有的切面类这里直接返回;
			shouldSkip(beanClass, beanName):
			获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】,每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor,判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;
			返回true如果是AspectJPointcutAdvisor的子类,则跳过,这里目标类返回false;
		 */
		if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
			// 切面类在advisedBeans[是否是增前Bean]的集合中标记为false,表示切面类是不增强的
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return null;
		}
	}
	
	// Create proxy here if we have a custom TargetSource.
	// Suppresses unnecessary default instantiation of the target bean:
	// The TargetSource will handle target instances in a custom fashion.
	// 这里也没有自定义的目标,返回null
	if (beanName != null) {
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			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;
}

所以目标类到这里没有通过 InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法创建出代理对象,最终还是调用AbstractAutowireCapableBeanFactory的doCreateBean方法创建Bean;

4. 目标类被增强生成代理类

通过doCreateBean创建组件的时候,调用AbstractAutowireCapableBeanFactory的initializeBean()方法执行目标类初始化的时候,在执行自定义初始化方法的后面,会调用BeanPostProcessor的postProcessAfterInitialization,所以就来到了AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialization()方法中,具体代码如下:

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 * org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(Object, String)
 */
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			// 这里很关键,目标类就是在这里被增强,最后生成代理类
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

其中org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(Object, String, Object)的代码如下: 

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	// 判断是否不需要增强的,切面类在AbstractAutoProxyCreator的postProcessBeforeInstantiation中就会标记为不增强,所有切面类到这里就直接返回组件
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	// 跟AbstractAutoProxyCreator的postProcessBeforeInstantiation中的一样,判断是否是aop的基础类的子类或者是否需要掉过,普通组件是不跳过的
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	// 这里很关键,通过目标组件找出与之相关的所有切面方法,封装为Object[] specificInterceptors, specificInterceptors的值如下: 
	/**
		[org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,
		InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)]; perClauseKind=SINGLETON, 
		InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterReturning(org.aspectj.lang.JoinPoint,java.lang.Object)]; perClauseKind=SINGLETON, 
		InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.after(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, 
		InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.before(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]
	*/
	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). 获取当前bean的所有增强器(通知方法)  Object[]  specificInterceptors
    1.1). 找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
    1.2). 获取到能在bean使用的增强器。
    1.3). 给增强器排序,排序很重要,涉及到增强器转为拦截器链的调用顺序,
            排序优先级是 @AfterThrowing > @AfterReturning > @After > @Before
2). 保存当前bean在advisedBeans中;
3). 如果当前bean需要增强,创建当前bean的代理对象;
    3.1). 获取所有增强器(通知方法)
    3.2). 保存到proxyFactory
    3.3). 创建代理对象:Spring自动决定
        JdkDynamicAopProxy(config);jdk动态代理;
        ObjenesisCglibAopProxy(config);cglib的动态代理;
4). 给容器中返回当前组件使用cglib增强了的代理对象;
5). 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;

找出与目标类匹配的增强器的具体代码流程如下:

//找出与组件相关的所有增强器(通知方法)
@Override
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();
	// 这里面就是根据切面类的切面表达式与目标类进行匹配
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		// 把与目标组件匹配的增强器进行排序(排序很重要,涉及到后面的目标方法调用,触发增强器调用链执行的流程)
		// 排完序的增强器如下:
		/**
			[org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, 
			InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)]; perClauseKind=SINGLETON, 
			InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.afterReturning(org.aspectj.lang.JoinPoint,java.lang.Object)]; perClauseKind=SINGLETON, 
			InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.after(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, 
			InstantiationModelAwarePointcutAdvisor: expression [pointCutCalculator()]; advice method [public void com.yibai.spring.annotation.aop.CalculatorAspect.before(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]\
			
			排序优先级是 @AfterThrowing > @AfterReturning > @After > @Before
				
		*/
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	// 返回所有与目标相关的增强器(通知方法)
	return eligibleAdvisors;
}

创建目标类代理类的具体代码如下:

protected Object createProxy(Class<?> beanClass, String beanName, 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
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	// 创建代理对象:Spring自动决定, 最后返回目标类的代理
	return proxyFactory.getProxy(getProxyClassLoader());
}

在org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(AdvisedSupport)中,Spring自动选择创建代理类:

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

最后,生成的被增强后的代理类注册到IOC容器中;

 

    原文作者:AOP
    原文地址: https://blog.csdn.net/luojinbai/article/details/86709798
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞