Spring源码学习笔记之AOP源码

一、概述

Spring中的AOP其实是通过动态代理来实现的,在bean的后置处理时,通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来生成代理类

二、@EnableAspectJAutoProxy

我们知道开启AOP是通过EnableAspectJAutoProxy注解,不然所有的切面都不会生效,下面我们来看下这个注解做了哪些事

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class MyConfig {
    ...
}

@Aspect
@Component
public class LogAspects {
    ...
}

点击注解EnableAspectJAutoProxy进去看

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

可以看到这边有Import注解,我们知道Import注解可以导入一个ImportBeanDefinitionRegistrar接口的实现类,实现类的registerBeanDefinitions方法会在容器刷新过程中的invokeBeanFactoryPostProcessors被调用,

具体一会看,我们先看看AspectJAutoProxyRegistrar这个类,混个眼熟

//AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      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);
         }
      }
   }

}

三、AnnotationAwareAspectJAutoProxyCreator

首先我们回顾下Spring核心方法refresh中的两个方法invokeBeanFactoryPostProcessors和registerBeanPostProcessors

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //省略...

        try {
            //省略...

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            //省略...
        }

        catch (BeansException ex) {
            //省略...
        }

        finally {
            //省略...
        }
    }
}

我们在AspectJAutoProxyRegistrar类的registerBeanDefinitions方法上打个断点,启动一下服务,可以看到通过容器刷新方法中的invokeBeanFactoryPostProcessors这一步,最终会走到AspectJAutoProxyRegistrar类的这个

registerBeanDefinitions方法中,其实这边的知识是关于Import注解相关的,以后有机会再详细说

下面我们重点看下AspectJAutoProxyRegistrar类的registerBeanDefinitions方法

//AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      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);
         }
      }
   }

}

点击registerAspectJAnnotationAutoProxyCreatorIfNecessary进去,一路往里进,最终到AopConfigUtils类的registerOrEscalateApcAsRequired方法

//AopConfigUtils
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {

    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

//注意这个cls参数是AnnotationAwareAspectJAutoProxyCreator.class,记住这个类
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
        Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }

    //包装成BeanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    //把优先级调成最高
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    //注册AnnotationAwareAspectJAutoProxyCreator这个BeanDefinition,
    //名字叫org.springframework.aop.config.internalAutoProxyCreator
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

这个时候,AnnotationAwareAspectJAutoProxyCreator已经放到了beanDefinitionMap里,等待被实例化和初始化,那么AnnotationAwareAspectJAutoProxyCreator是在什么时候实例化和初始化的呢,我们先看下AnnotationAwareAspectJAutoProxyCreator的类图

可以看到AnnotationAwareAspectJAutoProxyCreator是BeanPostProcessor接口的实例,而BeanPostProcessor的实例化和初始化是registerBeanPostProcessors中完成的,我们找到这段代码,从上面我们知道AnnotationAwareAspectJAutoProxyCreator是加了Order属性的,所以走的是如下这段代码

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    //省略...

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    //省略...
}

可以看到9行getBean,点进去,进入到类AbstractBeanFactory的getBean方法

//AbstractBeanFactory
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return doGetBean(name, requiredType, null, false);
}

看过Spring中bean初始化代码的小伙伴都熟悉了,doGetBean中就是对bean做初始化,到此时AnnotationAwareAspectJAutoProxyCreator完成了初始化,放到了容器中,我们知道AnnotationAwareAspectJAutoProxyCreator是实现了BeanPostProcessor接口的实例,会在bean对象创建之后调用其postProcessAfterInitialization方法,这个方法在抽象父类AbstractAutoProxyCreator中

//AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            //包装如果必要的话
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

继续点击7行wrapIfNecessary进去

//AbstractAutoProxyCreator
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;
    }

    // 看一看这个bean有没有通知方法或者增强器,如果有就创建代理对象
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        //把bean包装成代理对象proxy
        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;
}

点击18行createProxy进去

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

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    //先创建proxyFactory工厂类,用于创建代理对象
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    //将当前bean适合的advice,重新封装成Advisor类,然后添加到ProxyFactory中
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

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

    //封装成代理类
    return proxyFactory.getProxy(getProxyClassLoader());
}

点击34行getProxy进到ProxyFactory类的getProxy方法中

//ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

继续点击getProxy来到接口AopProxy中

//AopProxy
Object getProxy(@Nullable ClassLoader classLoader);

我们看看getProxy的实现

可以看到分为两种创建代理类的方式,分别是jdk和cglib,选择jdk的方式看下

//JdkDynamicAopProxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    //jdk动态代理的标准用法
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

可以看到jdk动态代理的标准用法

四、过程总结

1、在容器刷新过程中的invokeBeanFactoryPostProcessors方法里把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap里;

2、在容器刷新过程中的registerBeanPostProcessors方法里完成了初始化;

3、AnnotationAwareAspectJAutoProxyCreator类的postProcessAfterInitialization方法(实际在其父类AbstractAutoProxyCreator中)讲所有有advice的bean对象重新包装成proxy对象;

4、调用bean方法是会通过其代理类proxy来依次调用增强器的相关方法;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步亿点点的小码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值