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如果是单例,将跟以前一样添加到缓存对象中。

  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/lay2017/p/11519411.html
Copyright © 2011-2022 走看看