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

Spring5 AOP——AbstractAutoProxyCreator横切逻辑的加载与解析

来源:互联网 收集:自由互联 发布时间: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的实例化之前被调用的。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { //当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类, // 则在 targetSourcedBeans 中将添加 beanName, // 也就是 targetSourcedBeans 中含有 beanName // 则说明这个类被动态代理了 private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16); private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256); /** * 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后) * AOP解析切面以及事务解析事务注解都是在这里完成的 * @param beanClass the class of the bean to be instantiated * @param beanName the name of the bean * @return */ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //获取BeanClass的缓存key Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //advisedBeans保存了所有已经做过动态代理的Bean // 如果被解析过则直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } // 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解) // 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息, // 而事务在这里是不会解析的) if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { 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. //获取用户自定义的targetSource, 如果存在则直接在对象实例化之前进行代理创建, // 避免了目标对象不必要的实例化 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //如果有自定义targetSource就要这里创建代理对象 //这样做的好处是被代理的对象可以动态改变,而不是值针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象 if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } //获取Advisors, 这个是交给子类实现的 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); //返回代理的对象 return proxy; } return null; } }

AbstractAutoProxyCreator的postProcessBeforeInstantiation方法是在AbstractAutowireCapableBeanFactory类中的createBean方法中的创建Bean实例方法doCreateBean方法的前一步方法resolveBeforeInstantiation方法中被最终调用的。

resolveBeforeInstantiation

  • 实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { @Nullable 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. //1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { //2.解析beanName对应的Bean实例的类型 Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor) bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //4.如果返回的bean不为空,会跳过Spring默认的实例化过程 //所以只能在这里调用BeanPostProcessor实现类的PostProcessorsAfterInitialization方法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } //5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析 mbd.beforeInstantiationResolved = (bean != null); } return bean; } @Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { //1.遍历当前BeanFactory中的BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { //2.应用InstantiationAwareBeanPostProcessor后置处理器,允许PostProcessorBeforeInstantiation方法返回bean对象的代理 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //3.执行postProcessBeforeInstantiation方法,在Bean实例化前操作, //该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的"正规流程" Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { //4.如果result不为null,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程。 return result; } } } return null; } }

因为AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,所以,resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法中的代码ibp.postProcessBeforeInstantiation(beanClass, beanName)方法最终调用的是AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法完成的AOP相关横切逻辑的加载与解析的。

TargetSource

postProcessBeforeInstantiation方法中出现了TargetSource。

 

TargetSource(目标源)是被代理的target(目标对象)实例的来源。TargetSource被用于获取当前MethodInvocation(方法调用)所需要的target(目标对象),这个target通过反射的方式被调用(如:method.invode(target,args))。换句话说,proxy(代理对象)代理的不是target,而是TargetSource,这点非常重要!!!

 

通常情况下,一个proxy(代理对象)只能代理一个target,每次方法调用的目标也是唯一固定的target。但是,如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:target pool(目标对象池)、hot swap(运行时目标对象热替换),等等。

public interface TargetSource extends TargetClassAware { /** * 返回当前目标源的目标类型 * 可以返回null值,如:EmptyTargetSource(未知类会使用这个目标源) */ @Override @Nullable Class<?> getTargetClass(); /** * 当前目标源是否是静态的。 * 如果为false,则每次方法调用结束后会调用releaseTarget()释放目标对象. * 如果为true,则目标对象不可变,也就没必要释放了。 */ boolean isStatic(); /** * 获取一个目标对象。 * 在每次MethodInvocation方法调用执行之前获取。 */ @Nullable Object getTarget() throws Exception; /** * 释放指定的目标对象。 */ void releaseTarget(Object target) throws Exception; }

详细的TargetSource:

Spring5AOP——TargetSource

getCustomTargetSource

  • 获取用户自定义的targetSource,如果存在则直接在对象实例化之前进行代理创建,避免了目标对象不必要的实例化。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { @Nullable protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { // We can't create fancy target sources for directly registered singletons. if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) { for (TargetSourceCreator tsc : this.customTargetSourceCreators) { TargetSource ts = tsc.getTargetSource(beanClass, beanName); if (ts != null) { // Found a matching TargetSource. if (logger.isTraceEnabled()) { logger.trace("TargetSourceCreator [" + tsc + "] found custom TargetSource for bean with name '" + beanName + "'"); } return ts; } } } // No custom TargetSource found. return null; } }
  • 如果获取到用户自定义的targetSource实例,那么就要会走后续的创建AOP的动态代理的流程。
  • 成功创建代理之后,就将代理的类型放入到proxyTypes缓存中,便于后续的获取,之后将代理实例返回。
  • 这就就完成了AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的执行。

到这里AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的下半部分就攻克了,现在回到上半部分。

!this.targetSourcedBeans.contains(beanName)

回到AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法中,如果此时传入的beanName没有出现在用户自定义的targetSourcedBeans缓存列表里面,则会进入到下面方法里面。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { //当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类, // 则在 targetSourcedBeans 中将添加 beanName, // 也就是 targetSourcedBeans 中含有 beanName // 则说明这个类被动态代理了 private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256); /** * 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后) * AOP解析切面以及事务解析事务注解都是在这里完成的 * @param beanClass the class of the bean to be instantiated * @param beanName the name of the bean * @return */ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //获取BeanClass的缓存key Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //advisedBeans保存了所有已经做过动态代理的Bean // 如果被解析过则直接返回 if (this.advisedBeans.containsKey(cacheKey)) { return null; } // 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解) // 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息, // 而事务在这里是不会解析的) if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } ...... return null; } }

isInfrastructureClass(beanClass)

  • 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator { @Override protected boolean isInfrastructureClass(Class<?> beanClass) { return (super.isInfrastructureClass(beanClass) || (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass))); } } public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { protected boolean isInfrastructureClass(Class<?> beanClass) { boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass); if (retVal && logger.isTraceEnabled()) { logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]"); } return retVal; } }

如果beanClass是Spring AOP的基础服务类的话,将对应于该Bean的cacheKey作为key添加到advisedBeans里面,并且将其对应的值设置为false,以标识这个是已经处理过的不需要包装的Spring AOP基础服务Bean。

shouldSkip(beanClass, beanName)

  • 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,而事务在这里是不会解析的)
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator { @Override protected boolean shouldSkip(Class<?> beanClass, String beanName) { // TODO: Consider optimization by caching the list of the aspect names //找到候选的Advisors List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); } }

findCandidateAdvisors()

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator { @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) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; } }

super.findCandidateAdvisors()

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator { @Nullable private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } }

this.advisorRetrievalHelper.findAdvisorBeans()

  • 获取容器里面的AdvisorBean
public class BeanFactoryAdvisorRetrievalHelper { private final ConfigurableListableBeanFactory beanFactory; @Nullable private volatile String[] cachedAdvisorBeanNames; 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<>(); } List<Advisor> advisors = new ArrayList<>(); for (String name : advisorNames) { if (isEligibleBean(name)) { // 创建中的 bean 会被忽略 if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isTraceEnabled()) { logger.trace("Skipping currently created advisor '" + name + "'"); } } else { try { 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; } } } } return advisors; } }

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

  • 以注解的形式尝试从容器加载注解形式的Advisors

aspectJAdvisorsBuilder.buildAspectJAdvisors()方法主要作用

  • 从容器中获取所有的bean
  • 遍历beanName,解析出被@Aspect标记的类
  • 提取Aspect类里的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; 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的名称 for (String beanName : beanNames) { 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)) { //是切面类 //加入到缓存中 aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //Aspect里面的advice和pointcut被拆分成一个个的advisor, // advisor里的advice和pointcut是1对1的关系 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { //单例则直接将Advisor类存到缓存 this.advisorsCache.put(beanName, classAdvisors); } else { // 否则将其对应的工厂缓存 this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new ArrayList<>(); for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; } }

this.advisorFactory.getAdvisors(factory)

  • Aspect里面的advice和pointcut被拆分成一个个的advisor。
  • advisor里的advice和pointcut是1对1的关系。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable { @Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //获取Aspect的类Class Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取Aspect的类名 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //校验切面类 validate(aspectClass); // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. //我们使用的是包装模式来包装我们的MetadataAwareAspectInstanceFactory // 构建为MetadataAwareAspectInstanceFactory MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); //获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法 for (Method method : getAdvisorMethods(aspectClass)) { //循环解析切面中的方法 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. // 处理Introduction相关的Advice for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } }

getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

  • 获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法。
  • 循环解析切面中的方法。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable { @Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //切面的方法上构建切点表达式 AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } //实例化我们的切面Advisor对象 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); } }

getPointcut()

  • 切面的方法上构建切点表达式
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable { @Nullable private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { //找到Advice注解标签,并解析注解标签里面的pointCut属性值存储在AspectJAnnotation里 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]); ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; } }

new InstantiationModelAwarePointcutAdvisorImpl()

  • 实例化我们的切面Advisor对象
final class InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable { public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //当前的Pointcut表达式 this.declaredPointcut = declaredPointcut; //切面的class对象 this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //切面方法的名称 this.methodName = aspectJAdviceMethod.getName(); //切面方法的参数类型 this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //切面方法对象 this.aspectJAdviceMethod = aspectJAdviceMethod; //aspectj的Advisor工厂 this.aspectJAdvisorFactory = aspectJAdvisorFactory; //aspect的实例工厂 this.aspectInstanceFactory = aspectInstanceFactory; //切面的顺序 this.declarationOrder = declarationOrder; //切面的名称 this.aspectName = aspectName; //判断当前的切面对象是否需要延时加载 if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; //将切面中的通知构造为advice通知对象 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } } }

instantiateAdvice(this.declaredPointcut)

  • 将切面中的通知构造为advice通知对象
final class InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable { private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return (advice != null ? advice : EMPTY_ADVICE); } } public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable { @Override @Nullable public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { //获取我们的切面类的class对象 Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); validate(candidateAspectClass); //获取切面方法上的注解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } // If we get here, we know we have an AspectJ method. // Check that it's an AspectJ-annotated class //判断是否是注解切面对象 if (!isAspect(candidateAspectClass)) { throw new AopConfigException("Advice must be declared inside an aspect type: " + "Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); } if (logger.isDebugEnabled()) { logger.debug("Found AspectJ method: " + candidateAdviceMethod); } AbstractAspectJAdvice springAdvice; //判断标注在方法上的注解类型 switch (aspectJAnnotation.getAnnotationType()) { //是PointCut注解 那么就抛出异常 因为在外面传递进来的方法已经排除了Pointcut的方法 case AtPointcut: if (logger.isDebugEnabled()) { logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; //环绕通知 构建AspectJAroundAdvice case AtAround: springAdvice = new AspectJAroundAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //前置通知 构建AspectJMethodBeforeAdvice case AtBefore: springAdvice = new AspectJMethodBeforeAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //后置通知 AspectJAfterAdvice case AtAfter: springAdvice = new AspectJAfterAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; //返回通知 AspectJAfterReturningAdvice case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { springAdvice.setReturningName(afterReturningAnnotation.returning()); } break; //异常通知 AspectJAfterThrowingAdvice case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice( candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { springAdvice.setThrowingName(afterThrowingAnnotation.throwing()); } break; default: throw new UnsupportedOperationException( "Unsupported advice type on method: " + candidateAdviceMethod); } // Now to configure the advice... //设置我们构建出来的通知对象的相关属性比如DeclarationOrder, // 在代理调用的时候,责任链顺序上会用 springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } springAdvice.calculateArgumentBindings(); return springAdvice; } }

至此,就完成了Spring AOP横切逻辑的加载与解析。

 

参考: https://segmentfault.com/a/1190000015830477

https://www.cnblogs.com/foreveravalon/p/8653832.html

https://www.cnblogs.com/qinzj/p/11415057.html

网友评论