zoukankan      html  css  js  c++  java
  • springboot启动流程(十一)aop切面处理过程

    所有文章

    https://www.cnblogs.com/lay2017/p/11478237.html

    正文

    spring的两大核心就是ioc和aop。在关于ioc依赖注入的文章中,我们了解了如何根据BeanDefinition创建Bean,然后在BeanPostProcessor中处理@Autowired和@Resource两个注解,自动注入Bean。

    本文将讲解另外一块核心内容,aop切面。

    AOP自动配置

    首先,aop切面基于springboot的自动配置。如果不了解自动配置,请参考自动配置机制的文章。

    为此,我们先找到aop自动配置的类AopAutoConfiguration

    @Configuration
    @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
    @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
    public class AopAutoConfiguration {
    
        @Configuration
        @EnableAspectJAutoProxy(proxyTargetClass = false)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
                matchIfMissing = false)
        public static class JdkDynamicAutoProxyConfiguration {
    
        }
    
        @Configuration
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
        public static class CglibAutoProxyConfiguration {
    
        }
    
    }

    我们将以Cglib为主要的了解对象,可以看到CglibAutoProxyConfiguration上注解了一个@EnableAspectJAutoProxy,它意味着开启切面代理,我们打开该注解

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

    我们看到,@Import注解导入了AspectJAutoProxyRegistrar。在自动配置的文章中,我们了解到ConfigurationClassParser将会处理@Import注解。这里我们不再关注如何处理@Import注解,直接打开AspectJAutoProxyRegistrar类看看

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            // 注册自动切面代理的创建器
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
            // 省略
        }
    
    }

    跟进registerAspectJAnnotationAutoProxyCreatorIfNecessary

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
        return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
    }

    继续跟进registerAspectJAnnotationAutoProxyCreatorIfNecessary

    public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            BeanDefinitionRegistry registry, @Nullable Object source) {
    
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

    我们看到,调用registerOrEscalateApcAsRequired方法指定了一个类AnnotationAwareAspectJAutoProxyCreator,这个类将作为创建代理的类

    跟进registerOrEscalateApcAsRequired方法

    private static BeanDefinition registerOrEscalateApcAsRequired(
            Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    
        //
        // 构建BeanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        // 注册到Bean容器
        registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
        return beanDefinition;
    }

    可以看到,最终是注册到了Bean容器中,作为BeanDefinition存在。我们可以认为aop的自动配置过程就是为了创建AnnotationAwareAspectJAutoProxyCreator这个类的BeanDefinition。

    注册AnnotationAwareAspectJAutoProxyCreator

    首先,我们先看看AnnotationAwareAspectJAutoProxyCreator的继承结构

    可以看到,AnnotationAwareAspectJAutoProxyCreator最终是实现了BeanPostProcessor,那BeanPostProcessor是什么时候被创建为Bean的呢?

    这里,我们得回到refresh容器过程的refresh方法中,跟进AbstractApplicationContext的refresh方法

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 
    
            try {
                // 
    
                // 注册BeanDefinition到容器
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // 注册后置处理器到容器
                registerBeanPostProcessors(beanFactory);
    
                //
            }
            //
        }
    }

    在注册BeanDefinition之后,就会把BeanPostProcessor的BeanDefinition转化为了Bean注册到容器中。registerBeanPostProcessors结束以后,AnnotationAwareAspectJAutoProxyCreator就以Bean的形式存在于BeanFactory中了。

    触发AnnotationAwareAspectJAutoProxyCreator

    接着,我们再看AnnotationAwareAspectJAutoProxyCreator被注册为Bean以后,是在什么位置被触发的。前面,ioc依赖注入的文章中我们提到过createBean方法,将会根据BeanDefinition创建Bean。

    跟进AbstractAutowireCapableBeanFactory的createBean方法

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        //
    
        try {
            // BeanPostProcessors 调用
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        //
    
        try {
            // 创建实例对象
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            //
            return beanInstance;
        }
        //
    }

    我们看到,在doCreateBean之前,先触发resolveBeforInstantiation方法,调用了AnnotationAwareAspectJAutoProxyCreator。

    切面解析

    跟进resolveBeforeInstantiation

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                //
                if (targetType != null) {
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    //
                }
            }
            //
        }
        return bean;
    }

    继续跟进applyBeanPostProcessorBeforeInstantiation方法

    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 触发postProcesBeforeInstantiation
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

    继续跟进AbstractAutoProxyCreator的postProcessBeforeInstantiation方法

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);
    
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
    
        //
        return null;
    }

    isInfrastructureCLass将返回false,跟进AspectJAwareAdvisorAutoProxyCreator的shouldSkip

    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        // 返回所有的通知,如@Before @After @AfterThrowing @Round
        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方法,将会从beanFactory中获得注解了@Aspect的类元数据,然后获取其中定义的Advisor。

    到这一步,我们就已经获得了完成了切面部分的解析工作。

    代理增强

    回到AbstractAutowireCapableBeanFactory的createBean方法

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        //
    
        try {
            // BeanPostProcessors 调用
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        //
    
        try {
            // 创建实例对象
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            //
            return beanInstance;
        }
        //
    }

    获取了Advisor,那么再看看Advisor被增强到Bean上的过程,跟进doCreateBean

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {
        //
    
        if (instanceWrapper == null) {
            // 创建实例对象
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        //
    
        Object exposedObject = bean;
        try {
            // 自动注入
            populateBean(beanName, mbd, instanceWrapper);
            // 初始化Bean,创建代理的入口
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    
        //
        return exposedObject;
    }

    我们找到initializeBean,这个初始化Bean的入口,将从这里开始关注代理增强部分,跟进initializeBean方法

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        //
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    
        return wrappedBean;
    }

    继续跟进applyBeanPostProcessorsAfterInitialization方法

    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

    这里将会调用AbstractAutoProxyCreator的postProcessAfterInitialization方法,跟进方法

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

    继续跟进wrapIfNecessary

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //
    
        // 获取适用于当前Bean的Advisors
        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;
    }

    getAdvicesAndAdvisorsForBean方法将会获取到可以增强到该Bean的Advisor,然后createProxy将会创建代理类,并一路返回,如果是单例,则注册到缓存中

    跟进createProxy看看创建代理

    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
        //
    
        // 获取可用的advisor
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
    
        //
        // 创建并返回代理对象
        return proxyFactory.getProxy(getProxyClassLoader());
    }

    跟进getProxy

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

    createAopProxy将会根据条件返回Cglib实现或者jdk动态代理的实现,然后调用它们的getProxy方法去获取代理对象

    总结

    本文省略了不少细节内容,大体逻辑是从:aop自动配置 -> 解析@Aspect切面对象 -> 代理增强,这么一个逻辑行文的。

    自动配置的核心就是为了导入一个AnnotationAwareAspectJAutoProxyCreator,该类实现了BeanPostProcessor。所以在创建Bean实例对象之前会触发解析@Aspect切面对象,获取Advisor。在生成Bean实例对象之后,会再触发该类对Bean实例对象做代理增强,增强的Advisor来自之前的解析结果。代理增强的实现有cglib和jdk动态代理两种。

    最后,增强过的代理Bean如果是单例,将跟以前一样添加到缓存对象中。

  • 相关阅读:
    搭建自己的 github.io 博客
    转:华为副总裁一封信:透露年薪千万的工作感悟,太震撼了!
    SNF开发平台WinForm之五-高级查询使用说明-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之四-开发-主细表管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之二-开发-单表表单管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    SNF开发平台WinForm之一-开发-单表表格编辑管理页面-SNF快速开发平台3.3-Spring.Net.Framework
    C#基础总结之八面向对象知识点总结-继承与多态-接口
    C#基础总结之七面向对象知识点总结1
    C#基础总结之六 DataTable (临时表/数据源) 和Datatable 名片练习
  • 原文地址:https://www.cnblogs.com/lay2017/p/11519411.html
Copyright © 2011-2022 走看看