Spring AOP原理

91 阅读4分钟

概念

术语说明
切面(Aspect)
连接点(JoinPoint)
切入点(PointCut)指具体织入的方法,AOP匹配的点
通知(Advice)定义增强代码切入到目标代码的时间点,是目标执行方法执行之前还是之后等
顾问(Advisor)将通知以更为复杂的方式织入到目标对象中,是将通知包装成更复杂切面的装配器

主要逻辑

  1. 获取所有已经设置了 @Aspect的注解的Bean
  2. 遍历 @Aspect中未有增加 @PointCut 注解的方法
  3. 遍历所有的方法,并生成对应的 Advisor ,主要实现类为 InstantiationModelAwarePointcutAdvisorImpl
  4. InstantiationModelAwarePointcutAdvisorImpl中,会遍历以下注解
  5. 在初始化其他的Bean的时候,会遍历当前所有的增强器,如果当前Bean的方法可以使用当前的增加器(有找到符合@PointCut 标注的方法),则会考虑进行创建当前Bean的代理类

源码分析

  • 开启AOP的方式

@EnableAspectJAutoProxy 启用AOP 看下@EnableAspectJAutoProxy源码

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
}

通过 @Import AspectJAutoProxyRegistrar 接着来看  AspectJAutoProxyRegistrar类有处理哪些事情

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 注册AspectJ的创建类
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);主要处理的内容是 注册 AnnotationAwareAspectJAutoProxyCreator

AspectJAwareAdvisorAutoProxyCreator的子类,处理所有 @AspcetJ标注的所以类 ,包括 Spring Advisors

类图如下: image.png 从上图中知道,AspectJAwareAdvisorAutoProxyCreator是实现 SmartInstantiationAwareBeanPostProcessor,主要是在为了在初始化Bean的时候,可以进行一些其他的处理,关注这个接口的两个方法

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
            // 1.
			// shouldSkip 会判断当前是否需要进行跳过,这里会初始化所有标识了 @Aspect的类
			// 同时也会获取到所有的已经实现 Advisor接口的对象
			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 = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 2.
                // 如果必要则会创建Bean的代理
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
  1. 首先来看下 shouldSkip
	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		// TODO: Consider optimization by caching the list of the aspect names
        // 主要是在 AnnotationAwareAspectJAutoProxyCreator里实现,会初始化 实现了 Advisor接口或者标注了 @Aspect注解的类
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}
	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		if (this.aspectJAdvisorsBuilder != null) {
            // 创建所有标注了 @Aspect的类为Advisor,实现为 InstantiationModelAwarePointcutAdvisorImpl
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
  1. 再来看下 wrapIfNecessary
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
        // 如果有advice 则创建代理,Advice 为 MethodInterceptor
        // 调用AopProxyFactory 创建Proxy代理对象
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
   	@Override
   	@Nullable
   	protected Object[] getAdvicesAndAdvisorsForBean(
   			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
           // 获取合适的Advisor
   		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   		if (advisors.isEmpty()) {
   			return DO_NOT_PROXY;
   		}
   		return advisors.toArray();
   	}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 获取当前所有的Advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 匹配可以使用的Adivsor
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new ArrayList<>();
        // 每个Advisor对应到 @Aspect中的一个方法
		for (Advisor candidate : candidateAdvisors) {
            // 确认哪些 Advisor可以使用
            // 可以使用的,加入到返回列表中
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
	public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
        // 由上面知道,当前是 InstantiationModelAwarePointcutAdvisorImpl
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
        // @PointCut 是否可以应用于当前类上,并获取 @PointCut上的表达式,进行和当前的类进行比对
        // pc 为 AspectJExpressionPointcut
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        // 遍历当前的类或者是interface中的方法,是否符合当前的匹配
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if (introductionAwareMethodMatcher != null ?
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}