Spring AOP的总体流程
- 1、注册解析AOP的服务
- 2、解析和加载横切逻辑
- 3、将横切逻辑织入目标Bean中
AnnotationAwareAspectJAutoProxyCreator继承体系图
AnnotationAwareAspectJAutoProxyCreator既实现了SmartInstantiationAwareBeanPostProcessor 又实现了BeanFactoryAware。就可以对容器做一些事情。
AnnotationAwareAspectJAutoProxyCreator 实现了Order接口,所以先于普通的BeanPostProcessor注册,并对普通BeanPostProcessor也能起作用。
AnnotationAwareAspectJAutoProxyCreator 是InstantiationAwareBeanPostProcessor,会在Bean被创建之前,在resolveBeforeInstantiation中被调用。
Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。
所以AbstractAutoProxyCreator类里面的实现的容器级别的后置处理器方法便是介入分析的点:
- 横切逻辑的加载主要是在AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法中,该方法是在Bean的实例化之前被调用的。
- 横切逻辑织入目标Bean中主要是在AbstractAutoProxyCreator类中的postProcessAfterInitialization方法中,该方法是在Bean的实例化之后被调用的。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//当 Bean 被循环引用, 并且被暴露了,
// 则会通过 getEarlyBeanReference 来创建代理类;
// 通过判断 earlyProxyReferences 中
// 是否存在 beanName 来决定是否需要对 target 进行动态代理
private final Map
AbstractAutoProxyCreator的postProcessAfterInitialization方法是在AbstractAutowireCapableBeanFactory类中的createBean方法中的创建Bean实例方法doCreateBean方法中的的对bean进行初始化方法initializeBean方法中被最终调用的。
initializeBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1.激活Aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
因为AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,所以,AbstractAutowireCapableBeanFactory类中的initializeBean方法中的applyBeanPostProcessorsAfterInitialization方法中的代码processor.postProcessAfterInitialization(result, beanName)方法最终调用的是AbstractAutoProxyCreator类中的postProcessAfterInitialization方法完成的AOP相关横切逻辑的织入的。
由于动态代理对象的创建,并不需要也不会去干预Bean的实例化、属性赋值以及初始化,而初始化结束才意味着Bean被创建完成,因此Spring会等到Bean初始化之后,也就是执行invokeAwareMethods方法之后,才会将相关的横切逻辑给织入到Bean里面。
通过前面的学习了解到,Spring AOP是通过Bean级别的后置处理器在Bean的生命周期中对Bean进行处理的,而针对Bean初始化完之后在进行介入的点就不是很多了,基本就只剩下applyBeanPostProcessorsAfterInitialization方法里面调用的BeanPostProcessor的postProcessAfterInitialization方法了,事实上Spring AOP也正是在此处对bean进行横切逻辑的织入的。
Spring AOP横切逻辑的织入过程:
getEarlyBeanReference
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
//当 Bean 被循环引用, 并且被暴露了,
// 则会通过 getEarlyBeanReference 来创建代理类;
// 通过判断 earlyProxyReferences 中
// 是否存在 beanName 来决定是否需要对 target 进行动态代理
private final Map
AbstractAutoProxyCreator类中的getEarlyBeanReference方法,是在AbstractAutowireCapableBeanFactory类中的getEarlyBeanReference方法中的exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName)代码处被调用
而AbstractAutowireCapableBeanFactory类中的getEarlyBeanReference方法又是在AbstractAutowireCapableBeanFactory类中的doCreateBean方法中的addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))代码处被调用,addSingletonFactory()方法是提前暴露Bean用于解决SpringIOC容器Bean的循环依赖问题的。
AbstractAutoProxyCreator横切逻辑织入的入口方法:
- postProcessAfterInitialization:正常流程的织入入口。
- getEarlyBeanReference:循环依赖的织入入口。
回到AbstractAutoProxyCreator的postProcessAfterInitialization方法
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//当 Bean 被循环引用, 并且被暴露了,
// 则会通过 getEarlyBeanReference 来创建代理类;
// 通过判断 earlyProxyReferences 中
// 是否存在 beanName 来决定是否需要对 target 进行动态代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//该方法将会返回代理类
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
如果if (this.earlyProxyReferences.remove(cacheKey) != bean)
条件满足
- 1、remove方法执行后返回null
- 2、先前发生循环依赖创建出来的Bean与此时完成初始化的Bean不是同一个
满足上面的两种情况之一,都会以此处的bean为准,对其进行后续的动态代理的织入,毕竟此处的bean已经走完正常的实例化、属性赋值以及初始化的流程了,是最接近成功的bean。
wrapIfNecessary
- 判断当前bean是否需要被代理,如果需要则进行封装
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* Spring实现Bean代理的核心方法。wrapIfNecessary在两处会被调用,一处是getEarlyBeanReference,
* 另一处是postProcessAfterInitialization
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已经被处理过
// 1.判断当前bean是否在targetSourcedBeans缓存中存在(已经处理过),如果存在,则直接返回当前bean
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要被织入逻辑的
// 2.在advisedBeans缓存中存在,并且value为false,则代表无需处理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//是不是基础的bean 是不是需要跳过的
// 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 返回匹配当前Bean的所有Advice\Advisor\Interceptor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5.如果存在增强器则创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建Bean对应的代理,SingletonTargetSource用于封装实现类的信息
// 5.1 创建代理对象:这边SingletonTargetSource的target属性存放的就是我们原来的bean实例(也就是被代理对象),
// 用于最后增加逻辑执行完毕后,通过反射执行我们真正的方法时使用(method.invoke(bean, args))
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 5.2 创建完代理后,将cacheKey -> 代理类的class放到缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理对象
return proxy;
}
//该Bean是不需要进行代理的,下次就不需要重复生成了
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
getAdvicesAndAdvisorsForBean
- 返回匹配当前Bean的所有Advice\Advisor\Interceptor
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 1.找到符合条件的Advisor
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
// 2.如果没有符合条件的Advisor,则返回null
return DO_NOT_PROXY;
}
return advisors.toArray();
}
}
findEligibleAdvisors
- 找到符合条件的Advisor
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
protected List findEligibleAdvisors(Class> beanClass, String beanName) {
//找到Spring IoC容器中所有的候选Advisor
List candidateAdvisors = findCandidateAdvisors();
//判断找到的Advisor能不能作用到当前的类上
List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
//对获取到的advisor进行排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
}
findCandidateAdvisors
- 找到Spring IoC容器中所有的候选Advisor
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
protected List findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
// 先尝试从缓存中获取容器中所有 Advisor bean 的名称
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
// 如果缓存为空,尝试从容器以及其父容器分析得到所有 Advisor bean 的名称
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 添加进缓存
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// 2.遍历处理advisorNames
List advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
// 创建中的 bean 会被忽略
// 2.1 跳过当前正在创建的advisor
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 2.2 通过beanName获取对应的bean对象,并添加到advisors
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
// 3.返回符合条件的advisor列表
return advisors;
}
}
关于AnnotationAwareAspectJAutoProxyCreator类中的findCandidateAdvisors方法的解读
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
@Override
protected List findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 使用注解方式配置AOP的时候还是能够支持对XML配置的AOP的支持的.
List advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
// 为bean工厂中的所有AspectJ方面构建advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
public class BeanFactoryAspectJAdvisorsBuilder {
private final ListableBeanFactory beanFactory;
private final AspectJAdvisorFactory advisorFactory;
@Nullable
private volatile List aspectBeanNames;
private final Map> advisorsCache = new ConcurrentHashMap<>();
private final Map aspectFactoryCache = new ConcurrentHashMap<>();
public List buildAspectJAdvisors() {
List aspectNames = this.aspectBeanNames;
// 1.如果aspectNames为空,则进行解析
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List advisors = new ArrayList<>();
//用于保存切面的名称的集合
aspectNames = new ArrayList<>();
//获取所有的beanName
// AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再
// 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历我们从IOC容器中获取处的所有Bean的名称
// 1.2 循环遍历所有的beanName,找出对应的增强方法
for (String beanName : beanNames) {
// 1.3 不合法的beanName则跳过,默认返回true,子类可以覆盖实现,AnnotationAwareAspectJAutoProxyCreator
// 实现了自己的逻辑,支持使用includePatterns进行筛选
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
//获取对应的bean的类型
Class> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//提取@Aspect注解标记的Class
if (this.advisorFactory.isAspect(beanType)) {
//是切面类
//加入到缓存中
// 将存在Aspect注解的beanName添加到aspectNames列表
aspectNames.add(beanName);
// 新建切面元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 获取per-clause的类型是SINGLETON
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// 使用BeanFactory和beanName创建一个BeanFactoryAspectInstanceFactory,主要用来创建切面对象实例
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//Aspect里面的advice和pointcut被拆分成一个个的advisor,
// advisor里的advice和pointcut是1对1的关系
// 1.5 解析标记AspectJ注解中的增强方法
List classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
//单例则直接将Advisor类存到缓存
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 否则将其对应的工厂缓存
// 如果不是单例,则将factory放到缓存,之后可以通过factory来解析增强方法
this.aspectFactoryCache.put(beanName, factory);
}
// 1.7 将解析的增强器添加到advisors
advisors.addAll(classAdvisors);
}
else {
// 如果per-clause的类型不是SINGLETON
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
// 名称为beanName的Bean是单例,但切面实例化模型不是单例,则抛异常
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
// 将factory放到缓存,之后可以通过factory来解析增强方法
this.aspectFactoryCache.put(beanName, factory);
// 解析标记AspectJ注解中的增强方法,并添加到advisors中
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
// 1.9 将解析出来的切面beanName放到缓存aspectBeanNames
this.aspectBeanNames = aspectNames;
// 1.10 最后返回解析出来的增强器
return advisors;
}
}
}
// 2.如果aspectNames不为null,则代表已经解析过了,则无需再次解析
// 2.1 如果aspectNames是空列表,则返回一个空列表。空列表也是解析过的,只要不是null都是解析过的。
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
// 2.2 aspectNames不是空列表,则遍历处理
List advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
// 根据aspectName从缓存中获取增强器
List cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
// 根据上面的解析,可以知道advisorsCache存的是已经解析好的增强器,直接添加到结果即可
advisors.addAll(cachedAdvisors);
}
else {
// 如果不存在于advisorsCache缓存,则代表存在于aspectFactoryCache中,
// 从aspectFactoryCache中拿到缓存的factory,然后解析出增强器,添加到结果中
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
// 返回增强器
return advisors;
}
}
更详细的横切逻辑的加载与解析:Spring5AOP——AbstractAutoProxyCreator横切逻辑的加载与解析
回到AbstractAdvisorAutoProxyCreator类的findEligibleAdvisors方法中
findAdvisorsThatCanApply
- 从所有候选的Advisor中找出符合条件的
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
protected List findAdvisorsThatCanApply(
List candidateAdvisors, Class> beanClass, String beanName) {
//给其ThreadLocal的成员变量 currentProxiedBeanName设置上正在创建动态代理的Bean
//以标注当前线程正在创建的动态代理是针对哪一个Bean的
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//委托AopUtils.findAdvisorsThatCanApply方法筛选出匹配Bean的Advisors
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
}
public final class ProxyCreationContext {
private static final ThreadLocal currentProxiedBeanName =
new NamedThreadLocal<>("Name of currently proxied bean");
@Nullable
public static String getCurrentProxiedBeanName() {
return currentProxiedBeanName.get();
}
static void setCurrentProxiedBeanName(@Nullable String beanName) {
if (beanName != null) {
currentProxiedBeanName.set(beanName);
}
else {
currentProxiedBeanName.remove();
}
}
}
AopUtils.findAdvisorsThatCanApply
- 委托AopUtils.findAdvisorsThatCanApply方法筛选出匹配Bean的Advisors
public abstract class AopUtils {
public static List findAdvisorsThatCanApply(List candidateAdvisors, Class> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
// 1.首先处理引介增强(@DeclareParents)用的比较少可以忽略,有兴趣的参考:21_AOP_Advice增强2(异常、引介)
//判断Advisor对象是不是实现了IntroductionAdvisor
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 2.遍历所有的candidateAdvisors
for (Advisor candidate : candidateAdvisors) {
// 2.1 引介增强已经处理,直接跳过
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 2.2 正常增强处理,判断当前bean是否可以应用于当前遍历的增强器(bean是否包含在增强器的execution指定的表达式中)
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}
AopUtils.canApply
- 判断当前Advisor的Pointcut是否匹配当前bean
public abstract class AopUtils {
public static boolean canApply(Advisor advisor, Class> targetClass, boolean hasIntroductions) {
//判断是否是IntroductionAdvisor
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
//判断是否是PointcutAdvisor
else if (advisor instanceof PointcutAdvisor) {
//转为PointcutAdvisor类型
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
//如果Advisor连Pointcut表达式都没有的话,就证明它是匹配所有Bean的
return true;
}
}
}
AopUtils.canApply(Pointcut pc, Class> targetClass, boolean hasIntroductions)
- canApply(pca.getPointcut(), targetClass, hasIntroductions)
public abstract class AopUtils {
public static boolean canApply(Pointcut pc, Class> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//对Bean进行初筛
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//判断如果当前Advisor所指代的方法的切点表达式如果是对任意方法都放行,则直接返回
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
// 这里将MethodMatcher强转为IntroductionAwareMethodMatcher类型的原因在于,
// 如果目标类不包含Introduction类型的Advisor,那么使用
// IntroductionAwareMethodMatcher.matches()方法进行匹配判断时可以提升匹配的效率,
// 其会判断目标bean中没有使用Introduction织入新的方法,则可以使用该方法进行静态匹配,从而提升效率
// 因为Introduction类型的Advisor可以往目标类中织入新的方法,新的方法也可能是被AOP环绕的方法
// IntroductionAwareMethodMatcher的主要实现类是AspectJExpressionPointcut,可以看看里面的实现
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
//判断匹配器是不是IntroductionAwareMethodMatcher
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set> classes = new LinkedHashSet<>();
//判断当前class是不是代理的class对象
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
//获取到targetClass所实现的接口的class对象,然后加入到集合中
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
//通过methodMatcher.matches来匹配方法
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
//通过方法匹配器进行匹配
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
}
matches
- !pc.getClassFilter().matches(targetClass)
- 对Bean进行初筛
public class AspectJExpressionPointcut extends AbstractExpressionPointcut
implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware {
@Override
public boolean matches(Class> targetClass) {
//获取类里的pointcut表达式
PointcutExpression pointcutExpression = obtainPointcutExpression();
try {
try {
//对被代理对象做类级别的初筛,只能匹配部分表达式(如within),
//不支持execution等表达式的部分写法
//对于精确到类上的execution表达式,该方法是支持精准匹配的
return pointcutExpression.couldMatchJoinPointsInType(targetClass);
}
catch (ReflectionWorldException ex) {
logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
// Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
if (fallbackExpression != null) {
return fallbackExpression.couldMatchJoinPointsInType(targetClass);
}
}
}
catch (Throwable ex) {
logger.debug("PointcutExpression matching rejected target class", ex);
}
return false;
}
}
到此getAdvicesAndAdvisorsForBean方法的调用链就分析的差不多了,回到AbstractAutoProxyCreator类中的wrapIfNecessary方法中。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
/**
* Spring实现Bean代理的核心方法。wrapIfNecessary在两处会被调用,一处是getEarlyBeanReference,
* 另一处是postProcessAfterInitialization
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已经被处理过
// 1.判断当前bean是否在targetSourcedBeans缓存中存在(已经处理过),如果存在,则直接返回当前bean
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要被织入逻辑的
// 2.在advisedBeans缓存中存在,并且value为false,则代表无需处理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//是不是基础的bean 是不是需要跳过的
// 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 返回匹配当前Bean的所有Advice\Advisor\Interceptor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5.如果存在增强器则创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建Bean对应的代理,SingletonTargetSource用于封装实现类的信息
// 5.1 创建代理对象:这边SingletonTargetSource的target属性存放的就是我们原来的bean实例(也就是被代理对象),
// 用于最后增加逻辑执行完毕后,通过反射执行我们真正的方法时使用(method.invoke(bean, args))
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 5.2 创建完代理后,将cacheKey -> 代理类的class放到缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理对象
return proxy;
}
//该Bean是不需要进行代理的,下次就不需要重复生成了
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
当执行完getAdvicesAndAdvisorsForBean方法之后,就可以从候选的Advisor列表里筛选出匹配于当前Bean的Advisor列表,获取到Advisor列表之后就会接着执行后续的创建动态代理的步骤了。
由于getAdvicesAndAdvisorsForBean筛选出匹配的Advisor了,将该Bean对应的cacheKey写入到advisedBeans中,并将对应的值设置为true,表示对该Bean进行过Spring AOP的处理了。
之后就会调用createProxy方法去创建目标代理对象实例,创建好动态代理实例之后,就会动态代理实例类型给保存到proxyTypes的缓存里面,并将动态代理实例返回,这样就完成了wrapIfNecessary方法的执行。
如果没有getAdvicesAndAdvisorsForBean没有筛选出匹配的Advisor的话,就证明该Bean不需要织入横切逻辑,此时就会在advisedBeans里给该Bean设置对应的cacheKey和false,以表明该bean是不需要被织入的。
参考:
https://segmentfault.com/a/1190000015830477
https://zhuanlan.zhihu.com/p/104521455