学一学Sping中的AOP【目标对象被代理前都发生了什么?】

107 阅读7分钟

Spring版本: 5.3.27

AspectJ版本: 1.9.22

JDK版本: 1.8

(本文前置文章)[juejin.cn/post/742886…]

1、 AnnotationAwareAspectJAutoProxyCreator构建

1.1 实例化过程

refresh方法中registerBeanPostProcessors实例化了AnnotationAwareAspectJAutoProxyCreator

image-20241024231441568

AnnotationAwareAspectJAutoProxyCreator初始化时,由于实现了BeanFactoryAware,调用setBeanFactory时实际调用AbstractAdvisorAutoProxyCreator的setBeanFactory方法。

 // AbstractAdvisorAutoProxyCreator
 public void setBeanFactory(BeanFactory beanFactory) {
     // this.beanFactory = beanFactory
     super.setBeanFactory(beanFactory);
     if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
         throw new IllegalArgumentException(
                 "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
     }
     
     initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
 }
 ​
 // AnnotationAwareAspectJAutoProxyCreator
 protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
     // AbstractAdvisorAutoProxyCreator.initBeanFactory --> this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
     super.initBeanFactory(beanFactory);
     if (this.aspectJAdvisorFactory == null) {
         // 会在aspectJAdvisorFactory实例化其他bean的过程中是否代理起作用
         this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
     }
     this.aspectJAdvisorsBuilder =
             new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
 }

1.2 AnnotationAwareAspectJAutoProxyCreator类关系图

AnnotationAwareAspectJAutoProxyCreator

2、 目标类实例化(work)

2.1 实例化work前的后置处理器

// AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
    // 省略部分代码...
    try {
        // 给后置处理器一个机会能够返回替代目标bean实例的代理
        // 这里实际上就是准备好了AspectJPointcutAdvisor,但是并没有对work进行代理
		// 要代理,肯定是先构建了目标类
		// work通过默认构造创建
		// initializeBean 调用初始化方法后 applyBeanPostProcessorsAfterInitialization(AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization)
        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);
    }
    // 省略部分代码...
}

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // AnnotationAwareAspectJAutoProxyCreator的存在,hasInstantiationAwareBeanPostProcessors()为true
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 在实例化bean前开始应用所有bean后置处理器
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // getBeanPostProcessorCache().instantiationAware -- > AnnotationAwareAspectJAutoProxyCreator
    for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        // AnnotationAwareAspectJAutoProxyCreator继承AbstractAutoProxyCreator
        // 此处的postProcessBeforeInstantiation在AbstractAutoProxyCreator中
        Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
            return result;
        }
    }
    return null;
}

// AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    // cacheKey --> "work"
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        // 1.判断是否基础设施类(Advice、Pointcut、Advisor、AopInfrastructureBean)||(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass))
        // aspectJAdvisorFactory是AnnotationAwareAspectJAutoProxyCreator初始化时创建的,所以不为空,work不是切面
        
        // 2.shouldSkip是AspectJAwareAdvisorAutoProxyCreator中一个关键的方法,俄罗斯套娃正式开始
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // 创建代理
    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;
}

2.1.1 shouSkip

  1. 找候选的Advisor
  2. 遍历候选Advisor,是AspectJPointcutAdvisor类型&&切面名称是beanName则跳过
  3. 遍历完都不满足

回忆一下,目前为止,容器中的beanDefinitionMap里躺着一个名为org.springframework.aop.aspectj.AspectJPointcutAdvisor#0org.springframework.aop.aspectj.AspectJPointcutAdvisor定义信息。

所以findCandidateAdvisors中必然涉及到Advisor的实例化:

先从容器中把Advisor类型的beanName取出来。

this.beanFactory.getBean(name, Advisor.class) 找容器要名为org.springframework.aop.aspectj.AspectJPointcutAdvisor#0、类型为Advisor的bean。

2.1.2 查找候选advisor

// AspectJAwareAdvisorAutoProxyCreator
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
                ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

// AnnotationAwareAspectJAutoProxyCreator
protected List<Advisor> findCandidateAdvisors() {
    // Add all the Spring advisors found according to superclass rules.
    List<Advisor> advisors = super.findCandidateAdvisors();
    // Build Advisors for all AspectJ aspects in the bean factory.
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

// AbstractAdvisorAutoProxyCreator
protected List<Advisor> findCandidateAdvisors() {
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    // advisorRetrievalHelper是在AnnotationAwareAspectJAutoProxyCreator初始化时创建的BeanFactoryAdvisorRetrievalHelper
    return this.advisorRetrievalHelper.findAdvisorBeans();
}

// BeanFactoryAdvisorRetrievalHelper
public List<Advisor> findAdvisorBeans() {
    // 缓存
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 在容器的bean定义信息中查找符合Advisor类型的beanName
        // org.springframework.aop.aspectj.AspectJPointcutAdvisor#0
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    if (advisorNames.length == 0) {
        return new ArrayList<>();
    }

    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Skipping currently created advisor '" + name + "'");
                }
            } else {
                try {
                    // 搞事情,只是想实例化一个work,结果一层套一层, work还被套在shouldSkip里,简直俄罗斯套娃。
                    // 这里又套进org.springframework.aop.aspectj.AspectJPointcutAdvisor#0
                    // AspectJPointcutAdvisor
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                } catch (BeanCreationException ex) {
                    // 省略部分代码...
                }
            }
        }
    }
    return advisors;
}

2.1.3 AspectJPointcutAdvisor#0的实例化

  • 找容器要AspectJPointcutAdvisor#0过程中又会来到resolveBeforeInstantiation的postProcessBeforeInstantiation
  • 由于AspectJPointcutAdvisor是基础设施类,直接被加入到advisedBeans中
  • 注意这里没有被套进shouldSkip,全身而退后就准备实例化了
  • mbd.hasConstructorArgumentValues()为true,所以会采用自动装配的构造来实例化AspectJPointcutAdvisor
  • 你问我mbd.hasConstructorArgumentValues()为啥为true? 因为在早前构建这个bean定义信息的时候加了一个构造参数值advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef); adviceDef就是个封装的bean定义信息(AspectJMethodBeforeAdvice)详见(前置文章)[juejin.cn/post/742886…]
// AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// 省略部分代码...

	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}
	
	// 省略部分代码...

}

// ConstructorResolver
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
    // 既然想通过代参构造实例化bean,那是不是得先解决参数
	resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
	// 参数搞定,构造方法搞定 创建AspectJPointcutAdvisor
	bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
	return bw;
}

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
	for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
		if (valueHolder.isConverted()) {
			resolvedValues.addGenericArgumentValue(valueHolder);
		} else {
			// resolveValueIfNecessary就会把AspectJPointcutAdvisor需要的参数AspectJMethodBeforeAdvice解析出来
			// 我猜这里面又会实例化一个玩意
			Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
					resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			resolvedValues.addGenericArgumentValue(resolvedValueHolder);
		}
	}				
}

2.1.4 参数AspectJMethodBeforeAdvice解析

// BeanDefinitionValueResolver
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	if (value instanceof BeanDefinition) {
		BeanDefinition bd = (BeanDefinition) value;
		// 这里要注意AspectJMethodBeforeAdvice的bean定义信息并没有直接存在容器的beanDefinitionMap里,它只是作为AspectJPointcutAdvisor定义信息的一部分
		// 这里取了个特别的bean名称,内部bean
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
}

private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
	RootBeanDefinition mbd = null;
	// 省略部分代码...
	
	// 果不其然,又开始实例化这个内部bean了
	// 中间经历了惨绝人寰、惨无人道的过程
	// populateBean方法注入了两个属性(aspectName:myAspect、declarationOrder:1)
	Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
	if (innerBean instanceof FactoryBean) {
		boolean synthetic = mbd.isSynthetic();
		innerBean = this.beanFactory.getObjectFromFactoryBean(
				(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
	}
	if (innerBean instanceof NullBean) {
		innerBean = null;
	}
	return innerBean;
	// 省略部分代码...

}

2.1.5 参数AspectJMethodBeforeAdvice实例化

  • 又又来到resolveBeforeInstantiation

  • 由于AspectJMethodBeforeAdvice是基础设施类,直接被加入到advisedBeans中

  • 注意这里没有被套进shouldSkip,全身而退后就准备实例化了

  • mbd.hasConstructorArgumentValues()为true,所以会采用自动装配的构造来实例化AspectJMethodBeforeAdvice

  • 你又问我mbd.hasConstructorArgumentValues()为啥为true?因为在早前构建这个bean定义信息的时候加了三个构造参数值:

    cav.addIndexedArgumentValue(METHOD_INDEX, methodDef);-->MethodLocatingFactoryBean

    cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);-->pointcutRef 字符串

    cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);-->SimpleBeanFactoryAwareAspectInstanceFactory

// ConstructorResolver
// 既然想通过代参构造实例化AspectJMethodBeforeAdvice,那是不是又得先解决参数
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
    // 又开始解析参数
	resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
	// 构造参数上面解析出来了,构造方法有了,构造AspectJMethodBeforeAdvice
	bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
	return bw;
}

// 这里跟之前处理AspectJPointcutAdvisor的参数有点区别,AspectJMethodBeforeAdvice需要三个参数,带有下标
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
    // 省略部分代码...
    
	for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
		int index = entry.getKey();
		if (index < 0) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Invalid constructor argument index: " + index);
		}
		if (index + 1 > minNrOfArgs) {
			minNrOfArgs = index + 1;
		}
		ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
		if (valueHolder.isConverted()) {
			resolvedValues.addIndexedArgumentValue(index, valueHolder);
		} else {
			// 核心还是在这里
			Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
			ConstructorArgumentValues.ValueHolder resolvedValueHolder =
					new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
			resolvedValueHolder.setSource(valueHolder);
			resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
		}
	}
    // 省略部分代码...
}

2.1.6 第一个参数MethodLocatingFactoryBean实例化

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	if (value instanceof BeanDefinition) {
		BeanDefinition bd = (BeanDefinition) value;
		// 碰到的第二个inner bean
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
}

private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
	RootBeanDefinition mbd = null;
	// 省略部分代码...
	

	// 让容器创建MethodLocatingFactoryBean
	// 使用默认构造实例化MethodLocatingFactoryBean
	// populateBean方法注入了两个属性(targetBeanName:myAspect、methodName:beforeWork)
	// initializeBean方法将属性method也初始化(method public void com.lazy.snail.aop.MyAspect.beforeWork())
	Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
	// MethodLocatingFactoryBean是个工厂bean,要想拿到真正的bean需要调工厂bean的getObject
	if (innerBean instanceof FactoryBean) {
		boolean synthetic = mbd.isSynthetic();
		// 就是把工厂bean的method属性返回出来了
		innerBean = this.beanFactory.getObjectFromFactoryBean(
				(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
	}
	if (innerBean instanceof NullBean) {
		innerBean = null;
	}
	return innerBean;
	// 省略部分代码...

}

public Method getObject() throws Exception {
	return this.method;
}

2.1.7 第二个参数myPointcut实例化

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	// 注意这里跟第一个参数的区别,此处的参数是一个运行时bean引用,处理逻辑跟普通的bean定义信息不同,前面都是作为inner bean处理的
	if (value instanceof RuntimeBeanReference) {
		RuntimeBeanReference ref = (RuntimeBeanReference) value;
		return resolveReference(argName, ref);
	}
}

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	// 省略部分代码...
	

	// 一通计算,resolvedName --> "myPointcut"
	resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
	// 通过"myPointcut"找到了AspectJExpressionPointcut的bean定义信息,敢问从何处来:从XML中<aop:pointcut解析而来 
	// 注意这个bean定义信息的scope作用域是原型(prototype)
	// 默认构造创建AspectJExpressionPointcut
	// 通过populateBean把属性expression赋值 execution(public void com.lazy.snail.aop.Work.doWork())  expression属性其实是父类AbstractExpressionPointcut的
	bean = this.beanFactory.getBean(resolvedName);
	
	// 省略部分代码...

}

2.1.8 第三个参数SimpleBeanFactoryAwareAspectInstanceFactory实例化

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
	if (value instanceof BeanDefinition) {
		BeanDefinition bd = (BeanDefinition) value;
		// 碰到的第三个inner bean
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
}


private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) {
	RootBeanDefinition mbd = null;
	// 省略部分代码...
	

	// 让容器创建SimpleBeanFactoryAwareAspectInstanceFactory
	// 使用默认构造实例化SimpleBeanFactoryAwareAspectInstanceFactory
	// populateBean方法注入了属性(aspectBeanName:myAspect)
	Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null);
	// MethodLocatingFactoryBean是个工厂bean,要想拿到真正的bean需要调工厂bean的getObject
	if (innerBean instanceof FactoryBean) {
		boolean synthetic = mbd.isSynthetic();
		// 就是把工厂bean的method属性返回出来了
		innerBean = this.beanFactory.getObjectFromFactoryBean(
				(FactoryBean<?>) innerBean, actualInnerBeanName, !synthetic);
	}
	if (innerBean instanceof NullBean) {
		innerBean = null;
	}
	return innerBean;
	// 省略部分代码...

}

2.3 work初始化后后置处理器处理

// AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			// bean需不需要包装一下
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

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;
	}
	// 都是false
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// 创建代理
	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、图解流程

aop实例化