SpringAop实现原理及源码解析

本文基于 SpringBoot5.1.8.RELEASE 版本源码解析

Spring IOC源码解析(1)
Spring IOC源码解析(2)
Spring拓展点及调用顺序总结

我们直接通过SpringBoot项目来调试,建议阅读此文前先熟悉 Spring IOC源码,对SpringBoot自动装配有了解。

0. 概念简述

  1. PointCut:定义了哪些方法需要被增强,或者说需要被拦截,切点。
  2. Advice:拦截后的方法具体需要做什么操作(@Before,@Around,@After做些什么事情)。
  3. Advisor:内部包含了PointCut属性和Advice属性的。

1. AnnotationAwareAspectJAutoProxyCreator

我们先看看这个关键类AnnotationAwareAspectJAutoProxyCreator的继承关系图。

最左上角,我们可以看到熟悉的BeanPostProcessor。

在此我们可以大致猜测到SpringAop也是在Bean初始化后返回一个代理对象。

2. AnnotationAwareAspectJAutoProxyCreator的注册

在这里插入图片描述

SpringBoot中使用自动装配的方式。我们可以看看spring-boot-autoconfigure-2.1.6.RELEASE.jar中org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

  1. AopAutoConfiguration

    @Configuration
    @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
    @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
    public class AopAutoConfiguration {
    
        //默认实现cglib方式,注册该bean
    	@Configuration
        //我们进去看看@EnableAspectJAutoProxy
    	@EnableAspectJAutoProxy(proxyTargetClass = true)
    	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
    			matchIfMissing = true)
    	public static class CglibAutoProxyConfiguration {
    
    	}
    
    }
    
  2. @EnableAspectJAutoProxy

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    //看看AspectJAutoProxyRegistrar
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
        
    }
    
  3. AspectJAutoProxyRegistrar

    //我们直接跟踪进去这行,看到AopConfigUtils注册了AnnotationAwareAspectJAutoProxyCreator.class
    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    

3. AOP源码解析

通过上面我们知道了AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor,同时也继承了InstantiationAwareBeanPostProcessor。

创建Bean的时候会调用先调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation和InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation;

再调用BeanPostProcessor.postProcessBeforeInitialization和BeanPostProcessor.postProcessAfterInitialization.

我们发现InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation和BeanPostProcessor.postProcessAfterInitialization有对应逻辑。而BeanPostProcessor.postProcessAfterInitialization包含InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation逻辑。所以我们就只看BeanPostProcessor.postProcessAfterInitialization。

3.1. AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            //如果需要代理,则进行以下逻辑
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

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;
    }
    //3.1.1 判断是否aop相关的(Advice、PointCut、Advisor、AopInfrastructureBean)类,这些类无需增强,调用的是子类AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass
    //判断是不是应该跳过 (AOP解析直接解析出我们的切面信息(并且把我们的切面信息进行缓存),我们先不跟进去
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    //返回匹配当前bean的所有advisor、advice、interceptor。也就是不管你使用的@Before,@After等方式都会返回一个,按照顺序形成一个调用链
    //3.1.2:1、获取所有advisor。2、把tagClass所有的方法都解析出来。3、通过advisor中的pointCut拦截点匹配方法判断是否是切点。4、如果是切点,返回该advisor
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        /:3.1.3:创建代理对象,我们进去看看
        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;
}

//3.1.1: 判断是否(Advice、PointCut、Advisor、AopInfrastructureBean)类
protected boolean isInfrastructureClass(Class<?> beanClass) {
    boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
        Pointcut.class.isAssignableFrom(beanClass) ||
            Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);
    return retVal;
}

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                             @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    //省略代码...

    // 3.1.3: 直接看获取代理对象
    return proxyFactory.getProxy(getProxyClassLoader());
}

3.1.1. AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass

@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
    // 是否aop相关的(Advice、PointCut、Advisor、AopInfrastructureBean)类,这些类无需增强(调用父类,就是上面的AbstractAutoProxyCreator.isInfrastructureClass)
    // 判断是否有@Aspect注解
    return (super.isInfrastructureClass(beanClass) ||
            (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}

3.1.2. AbstractAdvisorAutoProxyCreator

	@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
	
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//从BeanFactory中获取所有合格的Advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//遍历所有的Advisor,遍历目标类所有的方法,判断Advisor中定义的pointCut是否应用于改方法,返回对应的Advisor
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

3.1.3. ProxyFactory.getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    //我们先看看createAopProxy()这个方法,最终最终跟踪到如下方法类3。再看看getProxy,就是获取代理对象
    return createAopProxy().getProxy(classLoader);
}

3.1.4. AbstractAutoProxyCreator.createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                             @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
	
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    //建立一个ProxyFactory,把Advisor设置进去,把代理目标类targetSource设置进去
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    //通过这个工厂创建代理类
    return proxyFactory.getProxy(getProxyClassLoader());
}

3.1.5. DefaultAopProxyFactory.createAopProxy

//此处的AdvisedSupport config就是包含代理目标类的所有Advisors的一个对象
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    //判断返回使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy方式代理
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException();
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

3.1.6. 以上返回了proxy代理对象,执行的时候就调用相应的invoke方法,我们看看JdkDynamicAopProxy。

@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	//代理目标类
    TargetSource targetSource = this.advised.targetSource;
    Object target = null;

    try {
        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);

        //获取所有代理对象的拦截对象Advice,就是通过我们上面的ProxyFactory工厂设置进去的
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

        MethodInvocation invocation =
        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

        //通过责任链模式调用
        retVal = invocation.proceed();

        return retVal;
    }

}

4. 总结一下

  1. 启动时注册AnnotationAwareAspectJAutoProxyCreator,这是一个BeaPostProcessor,初始化时候会调用该类postProcessAfterInitialization方法进行包装返回代理类
  2. 初始化时:对需要进行代理的类,进行处理,获取该bean的Advisor,匹配bean里面的所有方法,是否需要代理。然后再返回所有Advisor/Advice/Intecepter拦截对象,组成一个数组,设置到proxyFactory中,通过proxyFactory创建对应的jdk或cglib代理类。
  3. 执行调用时,调用相应的代理类,并通过责任链模式调用bean所有Advice拦截对象处理相应代理逻辑。
  4. 本文简单的介绍了一下基础逻辑,详细代码有兴趣可以自行去阅读。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值