Spring--原理--AOP

原文网址:Spring--原理--AOP_IT利刃出鞘的博客-CSDN博客

其他网址

Spring AOP源码详细解析_my java博客园-CSDN博客
Spring5AOP——AbstractAutoProxyCreator横切逻辑织入目标Bean中 | 码农家园
面试官:Spring AOP是怎么实现的?_小识的博客-CSDN博客
最简 Spring AOP 源码分析 - 云+社区 - 腾讯云
spring AOP @EnableAspectJAutoProxy原理_sjtu_chenchen的专栏-CSDN博客
从@EnableAspectJAutoProxy分析Spring AOP原理_zhoushimiao1990的博客-CSDN博客
AOP系列(三)SpringBoot中 AOP实现原理

简介

版本

本文的版本:springboot:2.3.0.RELEASE;Spring:5.2.6.RELEASE。

说明

Spring AOP本质是用的代理模式,其基于BeanPostProcessor实现,从而能够与IOC结合起来。

AOP的核心类的分类

advisorCreator,继承 spring ioc的扩展接口 BeanPostProcessor,主要用来扫描获取 advisor。
advisor:通知者,封装了spring aop中的切点和通知。 就是我们常用的@Aspect 注解标记的类。
advice: 通知,也就是aop中增强的方法。

AnnotationAwareAspectJAutoProxyCreator

Spring--原理--AOP_第1张图片

实现了Order接口,所以先于普通的BeanPostProcessor注册,并对普通BeanPostProcessor也能起作用。

实现了InstantiationAwareBeanPostProcessor接口,所以会在Bean被创建之前被调用。

        Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。所以AbstractAutoProxyCreator类实现的容器级别的后置处理器方法是介入分析的点。

总览

Spring--原理--AOP_第2张图片

AbstractAutoProxyCreator:Spring 为Spring AOP 模块暴露的可扩展抽象类,也是 AOP 中最核心的抽象类。

BeanNameAutoProxyCreator:根据指定名称创建代理对象(阿里连接池框架druid也基于此类做了扩展)。通过设置 advisor,可以对指定的 beanName 进行代理。支持模糊匹配。

AbstractAdvisorAutoProxyCreator:功能比较强大,默认扫描所有Advisor的实现类。相对于根据Bean名称匹配,该类更加灵活。动态的匹配每一个类,判断是否可以被代理,并寻找合适的增强类,以及生成代理类。

DefaultAdvisorAutoProxyCreator:AbstractAdvisorAutoProxyCreator的默认实现类。可以单独使用,在框架中使用AOP,尽量不要手动创建此对象。

AspectJAwareAdvisorAutoProxyCreator:Aspectj的实现方式,也是Spring Aop中最常用的实现方式,如果用注解方式,则用其子类AnnotationAwareAspectJAutoProxyCreator。

AnnotationAwareAspectJAutoProxyCreator:目前最常用的AOP使用方式。spring aop 开启注解方式之后,该类会扫描所有@Aspect()注释的类,生成对应的advisor。目前SpringBoot框架中默认支持的方式,自动配置。本文我们就分析此类。

简要流程

开启AOP功能

AopAutoConfiguration实现Aop的自动装配,配置好依赖就能直接使用。此时有@EnableAspectJAutoProxy,开启AspectJ的代理功能。
AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar,实现registerBeanDefinitions方法
registerBeanDefinitions方法:向容器中注册bean:org.springframework.aop.config.internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

创建代理类对象 

AnnotationAwareAspectJAutoProxyCreator实现生命周期监听,后置处理AspectJ切入的类,查找缓存所有的Advisors,创建代理类对象。

  1. 解析和加载横切逻辑:AbstractAutoProxyCreator#postProcessBeforeInstantiation方法,在Bean实例化之前被调用。
  2. 创建代理类:AopProxy创建代理类,代理类里面会插入Advisor注解的方法中的代码,并返回代理对象
  3. 将横切逻辑织入目标Bean:AbstractAutoProxyCreator#postProcessAfterInitialization方法,在Bean实例化之后被调用。

DefaultAopProxyFactory提供代理策略,接口走JDK代理,类走Cglib代理。SpringBoot默认走Cglib代理。

执行目标方法

代理对象中的proxyFactory包含增强器和目标对象。
目标方法执行=> CglibAopProxy.intercept()=> 遍历所有的增强器,将其转为Interceptor,利用MethodInterceptor机制生成拦截器链,
如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
调用mi.proceed(),链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
拦截器链的机制,保证通知方法与目标方法的执行顺序

1.启用AOP

简介

spring-boot-starter-aop如何做到自动配置的?见:SpringBoot原理--自动配置_feiying0canglang的博客-CSDN博客

要使用AOP,首先要引入包。如果引入的是spring-aop包,则需要使用@EnableAspectJAutoProxy开启aop功能;如果引入的是spring-boot-starter-aop,则AOP就直接可以用了,无需加注解之类的开启它。

实际上,spring-boot-starter-aop是自动用了@EnableAspectJAutoProxy,所以我们还是从@EnableAspectJAutoProxy开始。

@EnableAspectJAutoProxy

EnableAspectJAutoProxy注解类上用了: @Import({AspectJAutoProxyRegistrar.class})

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}
  • proxyTargetClass 指定是否使用CGLIB的方式创建实现接口的目标对象的代理。缺省值为true,使用CGLIB方式创建对象的代理。

  • exposeProxy  标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。

AspectJAutoProxyRegistrar

总结

AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar,实现registerBeanDefinitions方法

向容器中注册bean:org.springframework.aop.config.internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

注册AnnotationAwareAspectJAutoProxyCreator

追踪:AspectJAutoProxyRegistrar#registerBeanDefinitions  //从名字就可以看出来,它是注册BeanDefinition用的。

registerBeanDefinitions //AspectJAutoProxyRegistrar
    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //AspectJAutoProxyRegistrar.java
        registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null); //AopConfigUtils.class
            registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); //AopConfigUtils.class

AopConfigUtils#registerOrEscalateApcAsRequired

private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
        BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }

        return null;
    } else {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", -2147483648);
        beanDefinition.setRole(2);
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
        return beanDefinition;
    }
}

开始的时候AutoProxyCreator类不存在,RootBeanDefinition初始化AnnotationAwareAspectJAutoProxyCreator类,注册类到IOC容器。

创建AnnotationAwareAspectJAutoProxyCreator

相关网址

refresh()、BeanPostProcessor

总结 

 AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),它在registerBeanPostProcessors()中处理,最终被实例化、设置属性、初始化。

分析

在上边“重要的类”可以得出:AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),那它会在registerBeanPostProcessors()中处理:

AbstractApplicationContext#refresh()
    registerBeanPostProcessors(beanFactory) //AbstractApplicationContext
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                getBean(String name, Class requiredType)   //AbstractBeanFactory
                    doGetBean(name, requiredType, null, false) //AbstractBeanFactory
                        createBean(beanName, mbd, args); //AbstractAutowireCapableBeanFactory
                            doCreateBean(beanName, mbdToUse, args);  //AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory#doCreateBean(beanName, mbdToUse, args); 主要做了如下几件事:

创建bean :createBeanInstance(beanName, mbd, args)
给bean中的属性赋值:populateBean(beanName, mbd, instanceWrapper)
初始化bean:initializeBean(beanName, exposedObject, mbd)

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {

    // Instantiate the bean.
    // 实例化bean
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    // 允许post-processors来修改合并的bean定义
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    // 初始化bean
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                            "] in its raw version as part of a circular reference, but has eventually been " +
                            "wrapped. This means that said other beans do not use the final version of the " +
                            "bean. This is often the result of over-eager type matching - consider using " +
                            "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

2.生成代理对象

3.执行目标方法

你可能感兴趣的:(Spring,原理,AOP)