返回

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

发布时间:2023-01-10 19:10:39 318
# html# java# spring# 容器# 信息

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 targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	private final Map> proxyTypes = new ConcurrentHashMap<>(16);

	private final Map 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 targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	private final Map 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 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 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) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
}

super.findCandidateAdvisors()

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
	@Nullable
	private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;

	protected List 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 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 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 aspectBeanNames;

	private final Map> advisorsCache = new ConcurrentHashMap<>();

	private final Map aspectFactoryCache = new ConcurrentHashMap<>();

	public List buildAspectJAdvisors() {
		List aspectNames = this.aspectBeanNames;

		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的名称
					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 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 advisors = new ArrayList<>();
		for (String aspectName : aspectNames) {
			List 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 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 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

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
Spring5 AOP——TargetSource 2023-01-10 18:50:23