Spring AOP源码分析(Spring Framework 5.3.7-SNAPSHOT)-阿里云开发者社区

开发者社区> gbYu> 正文

Spring AOP源码分析(Spring Framework 5.3.7-SNAPSHOT)

简介: 主要从以下几方面结合源码分析: 1.Spring容器启动流程; 2.Spring AOP相关的类如何注入Spring Ioc容器的以及代理对象的生成; 3.Spring AOP拦截器链的生成; 4.Spring AOP的调用过程; 5.AOP运用的设计模式;
+关注继续查看
本篇内容以注解的形式使用Spring AOP,所以这里容器使用的是AnnotationConfigApplicationContext
Spring Ioc容器的加载流程
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}
  • 首先是this(),此无参构造函数主要完成两件事

    • 调用AnnotationConfigApplicationContext的一系列父类的无参构造函数,初始化相关的属性,包括beanFactoryPostProcessors,beanFactory等重要属性;
    • 通过AnnotatedBeanDefinitionReader注册内置的postProcessor(实质是把<beanName,BeanDefinition>键值对放入DefaultListableBeanFactory的beanDefinitionMap属性中)

      • AnnotationConfigUtils#registerPostProcessor会注册以下后置处理器

        • ConfigurationClassPostProcessor(BeanDefinitionRegistryPostProcessor的实现类,主要解析主配置类、处理@Bean等注解)
        • AutowiredAnnotationBeanPostProcessor(SmartInstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor的实现类,本质是BeanPostProcessor)
        • CommonAnnotationBeanPostProcessor,设置@PostConstruct和@PreDestroy注解(在父类InitDestroyAnnotationBeanPostProcessor中)
        • 如果支持JPA,注册PersistenceAnnotationBeanPostProcessor
        • EventListenerMethodProcessor
        • DefaultEventListenerFactory
    • 构造ClassPathBeanDefinitionScanner实例对象(构造函数setResourceLoader,把Spring ioc容器转为ResourceLoader)
  • 注册配置类

    • 把配置类放入DefaultListableBeanFactory的beanDefinitionMap属性中
  • 刷新容器refresh()
  1. invokeBeanFactoryPostProcessors(beanFactory),主要完成的功能:往beanDefinitionNames中注册@Bean注解标注的方法返回的对象,如:业务逻辑类,切面类,@Import注解引入的类,

    • invokeBeanDefinitionRegistryPostProcessors

参数为上一步获取的后置处理器的bean集合,如:

- 首先从Spring容器中获取ConfigurationClassPostProcessor对应的bean;
- 然后解析配置类,流程是:ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
    ```
    // 创建配置类的解析器
    // Parse each @Configuration class
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
        // 开始解析
        parser.parse(candidates);
        parser.validate();

        Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        // Read the model and create bean definitions based on its content
        if (this.reader == null) {
            // 创建配置类BeanDefinition的解析器
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        // 解析@Bean注解标注的方法返回的对象,@Import注解引入的类,注入的对象
        this.reader.loadBeanDefinitions(configClasses);
    ```
    ConfigurationClassBeanDefinitionReader#loadBeanDefinitions
    ```
    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
        // 解析@Bean注解标注的类返回的对象
        loadBeanDefinitionsForBeanMethod(beanMethod);
    }

    loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
    // 解析@Import注解引入的类,注入的对象
    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
    ```
    - ConfigurationClassParser解析配置类,主要功能是填充configurationClasses属性(key,value都是解析后的ConfigurationClass的实例)
    - 解析ConfigurationClass,主要是得到beanMethods,importBeanDefinitionRegistrars属性值
    - ConfigurationClassBeanDefinitionReader#loadBeanDefinitions,主要功能是把上面解析得到的beanMethods注册到beanDefinitionMap中,以及调用AspectJAutoproxyRegistrar的registerBeanDefinitions方法,把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap中
  1. registerBeanPostProcessors(beanFactory)
  • 实例化AnnotationAwareAspectJAutoProxyCreator,并加入AbstractBeanFactory的beanPostProcessors属性中,
  • 往单例缓存池中加入internalAutoProxyCreator
  • 在获取internalAutoProxyCreator的实例过程中,会调用doCreateBean#setBeanFactory的aware接口,初始化与AOP获取advisors相关的一些类
    -总的逻辑;

    • 初始化BeanFactoryAdvisorRetrievalHelperAdapter对象
    • ReflectiveAspectJAdvisorFactory对象(解析切面,并获取advisors集合)
    • BeanFactoryAspectJAdvisorsBuilderAdapter(AnnotationAwareAspectJAutoProxyCreator的内部类,其父类是BeanFactoryAspectJAdvisorsBuilder,作用是解析切面,并获取advisors集合)对象
    • 源码:
    • 首先调用AbstractAdvisorAutoProxyCreator的setBeanFactory方法
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory);
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException(
                    "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
        }
        initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
    }
    • 然后调用AnnotationAwareAspectJAutoProxyCreator的initBeanFactoryff
    @Override
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.initBeanFactory(beanFactory);
        if (this.aspectJAdvisorFactory == null) {
            this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
        }
        // 内部类,它的父类是BeanFactoryAspectJAdvisorsBuilder
        this.aspectJAdvisorsBuilder =
                new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
    • 调用AbstractAdvisorAutoProxyCreator的initBeanFactory
    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }
  1. finishBeanFactoryInitialization(beanFactory)
  • 创建剩余非懒加载的bean,并存到单例缓存池,如:业务逻辑类,主配置类,切面类
  • 解析主配置类(如:aopConfig)时,在resolveBeforeInstantiation中AbstractAutoproxyCreator的postProcessBeforeInstantiation的shouldSkip中,

由ReflectiveAspectJAdvisorFactory#getAdvisors获取advisors(不包含ExposeInvocationInterceptor)

- 源码:
- 由ReflectiveAspectJAdvisorFactory(在上一步已创建对象)调用getAdvisors
```
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
            new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

List<Advisor> advisors = new ArrayList<>();
// 先获取切面的通知方法(加了通知注解的方法)
for (Method method : getAdvisorMethods(aspectClass)) {
    // 调用以下方法,获取每个通知的增强器,返回类型是InstantiationModelAwarePointcutAdvisorImpl
    Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
    if (advisor != null) {
        advisors.add(advisor);
    }
}
```
```
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
        int declarationOrderInAspect, String aspectName) {

    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

    AspectJExpressionPointcut expressionPointcut = getPointcut(
            candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
        return null;
    }

    // 构造函数中会创建advice
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
            this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
```
```
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
        Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    this.declaredPointcut = declaredPointcut;
    this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
    this.methodName = aspectJAdviceMethod.getName();
    this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
    this.aspectJAdviceMethod = aspectJAdviceMethod;
    this.aspectJAdvisorFactory = aspectJAdvisorFactory;
    this.aspectInstanceFactory = aspectInstanceFactory;
    this.declarationOrder = declarationOrder;
    this.aspectName = aspectName;

    if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        // Static part of the pointcut is a lazy type.
        Pointcut preInstantiationPointcut = Pointcuts.union(
                aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

        // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
        // If it's not a dynamic pointcut, it may be optimized out
        // by the Spring AOP infrastructure after the first evaluation.
        this.pointcut = new PerTargetInstantiationModelPointcut(
                this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
        this.lazy = true;
    }
    else {
        // A singleton aspect.
        this.pointcut = this.declaredPointcut;
        this.lazy = false;
        // 创建advice对象
        this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
    }
}
```
- InstantiationModelAwarePointcutAdvisorImpl的instantiateAdvice方法
```
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
            this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return (advice != null ? advice : EMPTY_ADVICE);
}
```
- 根据通知方法的注解,分别返回对应的AspectJXXXAdvice对象,@Around/@Before/@After/@Afterreturning/@AfterThrowing
```
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);

    AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }

    // If we get here, we know we have an AspectJ method.
    // Check that it's an AspectJ-annotated class
    if (!isAspect(candidateAspectClass)) {
        throw new AopConfigException("Advice must be declared inside an aspect type: " +
                "Offending method '" + candidateAdviceMethod + "' in class [" +
                candidateAspectClass.getName() + "]");
    }

    if (logger.isDebugEnabled()) {
        logger.debug("Found AspectJ method: " + candidateAdviceMethod);
    }

    AbstractAspectJAdvice springAdvice;

    switch (aspectJAnnotation.getAnnotationType()) {
        case AtPointcut:
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        case AtAround:
            springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore:
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
            springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
    }

    // Now to configure the advice...
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}
```
  • 解析被代理的业务逻辑类(如:mathCalculator)时,在doCreateBean中AbstractAutoproxyCreator的postProcessAfterInitialization中获取代理对象(advisors中添加ExposeInvocationInterceptor,

并调用AspectJAwareAdvisorAutoProxyCreator#sortAdvisors排序)

- 源码:
- 获取代理对象的入口
```
@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;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice.
    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;
}
```
- createProxy

创建代理对象,把之前解析主配置类得到的advisors集合作为参数传入,
在getProxy中,把ProxyCreatorSupport对象本身作为参数,传入到DefaultAopProxyFactory#createAopProxy方法,返回ObjenesisCglibAopProxy对象(ProxyCreatorSupport对象作为参数),初始化ObjenesisCglibAopProxy的父类CglibAopProxy,设置advised的值为(ProxyCreatorSupport类型的对象,其中包含advisors集合)
image.png

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);
    }
    // 依次调用父类AdvisedSupport,ProxyCreatorSupport的构造函数,
    // 分别声明advisorChainFactory = new DefaultAdvisorChainFactory(),
    // aopProxyFactory = new DefaultAopProxyFactory()
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);

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

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

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

    // Use original ClassLoader if bean class not locally loaded in overriding class loader
    ClassLoader classLoader = getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
        classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
    }
    return proxyFactory.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    return getAopProxyFactory().createAopProxy(this);
}
- DefaultAopProxyFactory的createAopProxy,根据是否实现接口,采用cglib动态代理或JDK动态代理
```
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!NativeDetector.inNativeImage() &&
            (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}
```
- 最后返回代理对象

Spring AOP通知集合如何获取以及代理对象的生成

image.png

  • 结合Spring Ioc容器的加载流程分析,在finishBeanFactoryInitialization这一步解析主配置类的bean,调用过程如下:

    • resolveBeforeInstantiation这一步,AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
    • AspectJAwareAdvisorAutoProxyCreator#shouldSkip
    • AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
    • BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors(这里BeanFactoryAspectJAdvisorsBuilder对象实例通过在registerBeanPostProcessors方法中创建)
    • ReflectiveAspectJAdvisorFactory调用相关类的方法

      • 如果是切面,由advisorFactory获取当前切面的所有通知advisors,并存储到advisorsCache(map类型,key是beanName,value是advisors)
      • 创建BeanFactoryAspectInstanceFactory对象factory
      • ReflectiveAspectJAdvisorFactory#getAdvisors(factory),参数是上一步中创建的factory

        • 创建LazySingletonAspectInstanceFactoryDecorator对象(创建MetadataAwareAspectInstanceFactory的装饰器,便于它只被实例化一次!)
        • getAdvisorMethods

通过反射得到切面类的通知方法,并循环遍历该集合,集合返回之前排序(按照Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class的顺序)

        - 返回InstantiationModelAwarePointcutAdvisorImpl对象,类型是Advisor
    - 如果是切面,最后把beanName加到aspectBeanNames(List类型,因为可以定义多个切面)中

image.png

    - 核心过程见上述的源码
  • 解析业务逻辑类,获取它的代理对象,获取过程如下[核心过程见上述的源码]:

    • doCreateBea -> initializingBean -> applyBeanPostProcessorsAfterInitialization
    • AbstractAutoProxyCreator#postProcessAfterInitialization
    • wrapIfNecessary 返回代理对象

      • AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean,从属性aspectBeanNames,advisorsCache中获取,他们赋值的地方在(finishBeanFactoryInitialization中,当beanName是aopConfig时,resolveBeforeInstantiation中解析切面)
      • extendAdvisors添加ExposeInvocationInterceptor.ADVISOR到集合的第一个
      • 把当前bean存入advisedBeans
      • createProxy

创建代理对象,把之前解析主配置类得到的advisors集合作为参数传入,
在getProxy中,把ProxyCreatorSupport对象本身作为参数,传入到DefaultAopProxyFactory#createAopProxy方法,返回ObjenesisCglibAopProxy对象(ProxyCreatorSupport对象作为参数),初始化ObjenesisCglibAopProxy的父类CglibAopProxy,设置advised的值为(ProxyCreatorSupport类型的对象,其中包含advisors集合)

        - 创建ProxyFactory对象proxyFactory,依次实例化:AdvisedSupport(创建默认的DefaultAdvisorChainFactory对象),ProxyCreatorSupport(创建默认的DefaultAopProxyFactory对象)
        - proxyFactory#getProxy
        - createAopProxy(),如果当前bean是接口,则返回JdkDynamicAopProxy对象,否则,返回ObjenesisCglibAopProxy对象
        - getProxy调用对应类的代理方法,生成bean的代理对象

Spring AOP拦截器链的生成
  • 以Cglib动态代理为例,CglibAopProxy执行拦截器链的生成
  • 当调用业务的逻辑方法时,代码会进入CglibAopProxy的内部类DynamicAdvisedInterceptor,intercept方法

    • 源码;
    @Override
        @Nullable
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Object target = null;
            TargetSource targetSource = this.advised.getTargetSource();
            try {
                if (this.advised.exposeProxy) {
                    // Make invocation available if necessary.
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
                // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
                target = targetSource.getTarget();
                Class<?> targetClass = (target != null ? target.getClass() : null);
                // 获取拦截器链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                // Check whether we only have one InvokerInterceptor: that is,
                // no real advice, but just reflective invocation of the target.
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    // We can skip creating a MethodInvocation: just invoke the target directly.
                    // Note that the final invoker must be an InvokerInterceptor, so we know
                    // it does nothing but a reflective operation on the target, and no hot
                    // swapping or fancy proxying.
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);
                }
                else {
                    // We need to create a method invocation...
                    // 开始链式的调用
                    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
                }
                retVal = processReturnType(proxy, target, method, retVal);
                return retVal;
            }
            finally {
                if (target != null && !targetSource.isStatic()) {
                    targetSource.releaseTarget(target);
                }
                if (setProxyContext) {
                    // Restore old proxy.
                    AopContext.setCurrentProxy(oldProxy);
                }
            }
        }
    • 调用AdvisedSupport的方法
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }
    • 进入DefaultAdvisorChainFactory,主要是把前面解析得到的AspectJXXXAdvice集合,转换为MethodInterceptor集合
    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, @Nullable Class<?> targetClass) {
    
        // This is somewhat tricky... We have to process introductions first,
        // but we need to preserve order in the ultimate list.
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        Advisor[] advisors = config.getAdvisors();
        List<Object> interceptorList = new ArrayList<>(advisors.length);
        Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
        Boolean hasIntroductions = null;
    
        for (Advisor advisor : advisors) {
            if (advisor instanceof PointcutAdvisor) {
                // Add it conditionally.
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    boolean match;
                    if (mm instanceof IntroductionAwareMethodMatcher) {
                        if (hasIntroductions == null) {
                            hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                        }
                        match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                    }
                    else {
                        match = mm.matches(method, actualClass);
                    }
                    if (match) {
                        MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                        if (mm.isRuntime()) {
                            // Creating a new object instance in the getInterceptors() method
                            // isn't a problem as we normally cache created chains.
                            for (MethodInterceptor interceptor : interceptors) {
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
            else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
            else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }
    
        return interceptorList;
    }
    • 转换用到了DefaultAdvisorAdapterRegistry,支持3种适配转换器:MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter
    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<>(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[0]);
    }
    • MethodBeforeAdviceAdapter
    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof MethodBeforeAdvice);
    }
    
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
    • AfterReturningAdviceAdapter
    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof AfterReturningAdvice);
    }
    
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
        return new AfterReturningAdviceInterceptor(advice);
    }
    • ThrowsAdviceAdapter
    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof ThrowsAdvice);
    }
    
    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        return new ThrowsAdviceInterceptor(advisor.getAdvice());
    }
Spring AOP的调用过程
  • MethodInvocation的链式生成过程,通过上一步获取拦截器链之后,调用CglibMethodInvocation的proceed,触发链式调用
  • 调用过程运用的软件设计模式是职责链模式

    • 调用过程源码:
    • new CglibMethodInvocation()
    public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
                Object[] arguments, @Nullable Class<?> targetClass,
                List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
    
            super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
    
            // Only use method proxy for public methods not derived from java.lang.Object
            this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
                    method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
                    !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
                    methodProxy : null);
        }
    • 调用父类ReflectiveMethodInvocation的构造函数
    protected ReflectiveMethodInvocation(
            Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
            @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
    
        this.proxy = proxy;
        this.target = target;
        this.targetClass = targetClass;
        this.method = BridgeMethodResolver.findBridgedMethod(method);
        this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
    }
    • 开始调用CglibMethodInvocation的proceed方法
    @Override
        @Nullable
        public Object proceed() throws Throwable {
            try {
                return super.proceed();
            }
            catch (RuntimeException ex) {
                throw ex;
            }
            catch (Exception ex) {
                if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
                        KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
                    // Propagate original exception if declared on the target method
                    // (with callers expecting it). Always propagate it for Kotlin code
                    // since checked exceptions do not have to be explicitly declared there.
                    throw ex;
                }
                else {
                    // Checked exception thrown in the interceptor but not declared on the
                    // target method signature -> apply an UndeclaredThrowableException,
                    // aligned with standard JDK dynamic proxy behavior.
                    throw new UndeclaredThrowableException(ex);
                }
            }
        }
    • 调用父类ReflectiveMethodInvocation的proceed方法,不断地从增强器中获取增强器,在ReflectiveMethodInvocation与子类CglibMethodInvocation来回调用,而且通过在各个MethodInterceptor实现类中实现链式调用
    @Override
    @Nullable
    public Object proceed() throws Throwable {
        // We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }
    
        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            // Evaluate dynamic method matcher here: static part will already have
            // been evaluated and found to match.
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
            if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // Dynamic matching failed.
                // Skip this interceptor and invoke the next in the chain.
                return proceed();
            }
        }
        else {
            // It's an interceptor, so we just invoke it: The pointcut will have
            // been evaluated statically before this object was constructed.
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
    • 按照调用栈从底向上,依次为ExposeInvocationInterceptor:
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = invocation.get();
        invocation.set(mi);
        try {
            return mi.proceed();
        }
        finally {
            invocation.set(oldInvocation);
        }
    }
    • AspectJAroundAdvice(如果有环绕通知)
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        if (!(mi instanceof ProxyMethodInvocation)) {
            throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
        }
        ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
        JoinPointMatch jpm = getJoinPointMatch(pmi);
        return invokeAdviceMethod(pjp, jpm, null, null);
    }
    • MethodBeforeAdviceInterceptor
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }
    • AspectJAfterAdvice
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        finally {
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }
    }
    • AfterReturningAdviceInterceptor
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
    • AspectJAfterThrowingAdvice
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        catch (Throwable ex) {
            if (shouldInvokeOnThrowing(ex)) {
                invokeAdviceMethod(getJoinPointMatch(), null, ex);
            }
            throw ex;
        }
    }
    • 当增强器都遍历完,则调用业务方法
    // We start with an index of -1 and increment early.
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }
    • 最后依次出栈,完成整个链式调用
AOP运用的设计模式
  • 职责链模式的出现背景是:把请求的发起者与处理者解耦,也就是说,客户端只管发送请求,至于请求该谁处理由请求链决定
  • 状态模式与职责链的不同在于:状态的改变条件,在类中是已经写好的,无法在客户端灵活设置
  • AOP拦截器链的执行过程,请求处理者的拦截器链是在切面中定义,可以灵活设置,请求沿着链传递(只是aop约定好了前置、后置、正常返回,异常返回这些切面逻辑)
总结
  • AOP拦截器链的执行,运用的软件设计模式

    • 责任链模式
  • 拦截器链advisor转换为MethodInterceptor的逻辑

    • 实现了MethodInterceptor接口

      • AspectJAfterThrowingAdvice
      • AspectJAfterAdvice
    • 未实现MethodInterceptor接口

      • AspectJAfterReturningAdvice
      • AspectJMethodBeforeAdvice
  • BeanFactoryAspectJAdvisorsBuilder中的advisorsCache在何时赋值?

    • BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法,同步块双重检查锁定中,先获取advisors,然后put到cache中
待细化
  • ReflectiveAspectJAdvisorFactory中的getAdvisorMethods()对切面中定义的@Befre/@Around/@After/@AfterReturning/@AfterThrowing注解标注的方法排序
  • 使用

    • AspectJ指示器:execution/@args/@annotations......
    • @AfterReturning可设置returing()属性
    • @AfterThrowing可以设置throwing()属性
  • @Around注解以及标注的方法的调用逻辑
  • 多切面,多个被拦截方法

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Spring AOP 源码分析——创建代理对象
1.简介 与筛选合适的通知器相比,创建代理对象的过程则要简单不少,本文所分析的源码不过100行,相对比较简单。在接下里的章节中,我将会首先向大家介绍一些背景知识,然后再去分析源码。
976 0
MaxCompute Studio使用心得系列3——可视化分析作业运行
我们很熟悉的是通过Logview 去分析作业的执行情况,logview上有很详细的执行日志,而Studio不仅仅提供可视化的信息,还会明确给出一些分析结论如job是有否长尾或数据倾斜情况。
3352 0
Okhttp3源码解析(1)-OkHttpClient分析
前言 上篇文章我们讲了Okhttp的基本用法,今天根据上节讲到请求流程来分析源码,那么第一步就是实例化OkHttpClient对象,所以我们今天主要分析下OkHttpClient源码! 初始化-构造方式 创建 OkHttpClient实例的两种方式 1.
2570 0
GraphScope 图分析引擎 - GRAPE 介绍
GraphScope 中的图分析引擎继承自 GRAPE,该系统实现了论文 Parallelizing Sequential Graph Computations 中提出的不动点计算模型
173 0
+关注
gbYu
极客coder
8
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载