当前位置 : 主页 > 编程语言 > java >

Spring5 AOP——AbstractAutoProxyCreator横切逻辑织入目标Bean中

来源:互联网 收集:自由互联 发布时间:2023-02-04
Spring AOP的总体流程 1、注册解析AOP的服务 2、解析和加载横切逻辑 3、将横切逻辑织入目标Bean中 AnnotationAwareAspectJAutoProxyCreator继承体系图 AnnotationAwareAspectJAutoProxyCreator既实现了SmartInsta

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<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16); @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; } }

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<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 2.在初始化前应用BeanPostProcessor的postProcessBeforeInitialization方法,允许对bean实例进行包装 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 3.调用初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 4.在初始化后应用BeanPostProcessor的postProcessAfterInitialization方法,允许对bean实例进行包装 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } // 5.返回wrappedBean return wrappedBean; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 1.遍历所有注册的BeanPostProcessor实现类,调用postProcessAfterInitialization方法 for (BeanPostProcessor processor : getBeanPostProcessors()) { // 2.在bean初始化后,调用postProcessAfterInitialization方法 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { // 3.如果返回null,则不会调用后续的BeanPostProcessors return result; } result = current; } return result; } }

因为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<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16); @Override public Object getEarlyBeanReference(Object bean, String beanName) { Object cacheKey = getCacheKey(bean.getClass(), beanName); this.earlyProxyReferences.put(cacheKey, bean); return wrapIfNecessary(bean, beanName, cacheKey); } }

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<Advisor> 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<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //找到Spring IoC容器中所有的候选Advisor List<Advisor> candidateAdvisors = findCandidateAdvisors(); //判断找到的Advisor能不能作用到当前的类上 List<Advisor> 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<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } public List<Advisor> 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<Advisor> 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<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. // 使用注解方式配置AOP的时候还是能够支持对XML配置的AOP的支持的. List<Advisor> 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<String> aspectBeanNames; private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>(); private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = new ConcurrentHashMap<>(); public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; // 1.如果aspectNames为空,则进行解析 if (aspectNames == null) { synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> 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<Advisor> 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<Advisor> advisors = new ArrayList<>(); for (String aspectName : aspectNames) { // 根据aspectName从缓存中获取增强器 List<Advisor> 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<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { //给其ThreadLocal<String>的成员变量 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<String> 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<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> 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<Class<?>> 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

上一篇:Spring5 AOP——创建AOP动态代理
下一篇:没有了
网友评论