Spring AOP底层源码分析

19 篇文章 5 订阅
12 篇文章 2 订阅

本文基于Spring5注解版进行分析

分两大块分析,

  • Spring创建AOP切面代理对象流程
  • AOP切面方法通知执行流程

Spring的AOP切面功能大家都用过,但是也会有一些人对AOP不是很理解,本文着重解析AOP的工作原理。

AOP是什么?

  • 对我们的业务方法实现增强,对执行方法进行拦截。
  • 实际就是利用JDK/CGLIB实现动态代理。

AOP应用场景,能帮我们干什么?

  • 控制层请求日志打印 ,保存。
  • 控制层权限控制。
  • 业务层分布式锁。
  • Spring 事务。

开始分析:

要用Spring AOP的切面功能,需要启用它,@EnableAspectJAutoProxy

相信大部分人用SpringBoot没有用过此注解,那是因为AspectJ的SpringBoot依赖帮我们自动注入了。

在这里插入图片描述

主要是向容器中注册了一个 AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator类图

Aware接口作用:从Spring上下文中获取实例数据的

  • BeanFactoryAware:拿到BeanFactory实例,IOC容器。
  • BeanClassLoaderAware:拿到当前应用类加载器。

BeanPostProcessor接口的作用:后置处理器

  • SmartInstantiationAwareBeanPostProcessor:预测Bean的类型,构造函数。
  • InstantiationAwareBeanPostProcessor:可以在容器创建对象前先创建对象。
  • BeanPostProcessor:可对实例化Bean做修改,比如给实例化对象属性重新复制,或创建代理

在这里插入图片描述


先演示一下:这里我定义一个拦截 service包下及其子包下的类的所有方法。

@Pointcut()的表达式这里不过多说,具体可以百度。

package com.liuqi.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class ServiceAop {

    @Pointcut("execution (* com.liuqi.service..*.*(..))")
    public void serviceAop() {}

    @Before(value = "serviceAop()")
    public void doBefore() {
        System.out.println("方法执行前通知");
    }

    @After(value = "serviceAop()")
    public void doAfter() {
        System.out.println("方法执行后通知");
    }

    @AfterReturning(value = "serviceAop()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("方法执行后的返回通知");
    }

    @AfterThrowing(value = "serviceAop()", throwing = "t")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable t) {
        System.out.println("方法执行异常通知");
    }

    @Around(value = "serviceAop()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知");
        Object proceed = joinPoint.proceed(); // 继续执行通知方法
        // 此返回结果,将影响我们实际执行的目标方法的方法结果
        return proceed;
    }
}

此service类只有一个方法

package com.liuqi.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void add() {
        System.out.println("add");
    }

}

效果截图:
在这里插入图片描述


开始进入正文

首先我们要知道,AOP创建代理对象是在BeanPostProcessor后置处理器的后置通知方法中进行工作的

先找到注册到容器类AnnotationAwareAspectJAutoProxyCreator中的实现方法postProcessAfterInitialization()

在父类AbstractAutoProxyCreator 中有该方法。核心方法wrapIfNecessary()

public class AbstractAutoProxyCreator {
    /**
     * 如果bean是,使用配置的拦截器创建一个代理被子类识别为要代理的。
     * @see #getAdvicesAndAdvisorsForBean
     */
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            /**
             * this.earlyProxyReferences 创建代理对象时的缓存
             */
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
}

1.0.0:wrapIfNecessary(bean, beanName, cacheKey);

是否需要创建代理对象。

public class AbstractAutoProxyCreator {
    /**
     * 如有必要,包装给定的bean,即它是否有资格被代理
     * @param bean the raw bean instance
     * @param beanName the name of the bean
     * @param cacheKey the cache key for metadata access
     * @return 包装bean或原始bean实例的代理
     */
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        /**
         * 如果标记的BeanName不需要创建代理
         */
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            /**
             * 如果标记的BeanName不需要创建代理 标记 false,
             * 预防创建多实例时下来的重复判断
             */
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        /**
         * 拿到适配此Bean实例的所有方法拦截器链  --> 通知方法
         * @Before, @After, @AfterReturning, @AfterThrowing, @Around
         * 且是一个排好序的,因为是(责任链模式执行的) --> 递归执行   后续会讲
         */
        // 1.0.1:重点分析
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            // 标记此BeanName需要创建代理
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            /**
             * 2.0.0:重点分析
             * 创建代理对象
             */
            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;
    }
}

1.0.1:getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

获取拦截器链 (通知方法链,所有可以适配当前Bean实例的通知方法),是一个排好顺序的数组。

public class AbstractAdvisorAutoProxyCreator {
    @Override
    @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        /**
         * 1.0.2:重点分析
         * 查找所有适配的通知方法
         */
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
}

1.0.2:findEligibleAdvisors(beanClass, beanName);

查找所有适配的通知方法

public class AbstractAdvisorAutoProxyCreator {
    /**
     * 查找所有适配此Bean的通知方法
     */
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        /**
         * 1.0.3:重点分析
         * 查找出所有的通知方法
         */
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        /**
         * 检查是否能够应用在此 Bean 实例上拦截
         */
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            /**
             * 将通知方法排序 默认的一个 -> AfterThrowing -> AfterReturning -> After -> Around -> Before
             * 执行会递归从后往前执行
             */
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
}

1.0.3:findCandidateAdvisors();

查找出所有的通知方法

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
    @Override
    protected List<Advisor> findCandidateAdvisors() {
        // 添加所有根据超类规则找到的Spring通知方法。
        List<Advisor> advisors = super.findCandidateAdvisors();
        /**
         * 重点记住 this.aspectJAdvisorsBuilder 在什么时候初始化的 后面分析
         *
         * 从bean工厂中的所有AspectJ切面类,构建通知方法。
         */
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
}

重点记住 this.aspectJAdvisorsBuilder 在什么时候初始化的 后面分析。
它保存了我们所有的切面类,和通知方法。

在这里插入图片描述


2.0.0:createProxy() 创建代理对象,非常重要

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    /**
     * 创建代理对象
     * @param beanClass bean 类型
     * @param beanName  bean name
     * @param specificInterceptors
     * @param targetSource 代理目标对象  --> Bean 实例
     * @return
     */
    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 = new ProxyFactory();
        proxyFactory.copyFrom(this);

        /**
         * 如果 @EnableAspectJAutoProxy(proxyTargetClass = false) 默认就是 false
         */
        if (!proxyFactory.isProxyTargetClass()) {
            /**
             * 设置是否直接代理目标类,而不仅仅是代理特定接口。默认为 fasle
             */
            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);
        }
        /**
         * 2.0.1:重点分析
         * 开始创建代理
         */
        return proxyFactory.getProxy(getProxyClassLoader());
    }
}

2.0.1:proxyFactory.getProxy(getProxyClassLoader());

创建代理对象

public class ProxyFactory extends ProxyCreatorSupport {
    public Object getProxy(@Nullable ClassLoader classLoader) {
        /**
        	2.0.2重点分析
         * createAopProxy() 创建AOP使用的代理器 JDK或CGLIB
         * getProxy()创建代理对象
         */
        return createAopProxy().getProxy(classLoader);
    }
}

2.0.2:createAopProxy()

创建AOP的代理器,JDK或者CGLIB

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        /**
         * @EnableAspectJAutoProxy(proxyTargetClass = true)
         * config.isProxyTargetClass() 是否开启强制使用CGLIB代理
         */
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            /**
             * 如果目标对象是个接口 || 当且仅当指定的类是动态的时
             */
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);  // JDK动态代理
            }
            return new ObjenesisCglibAopProxy(config);  // CGLIB 动态代理
        }
        else {
            return new JdkDynamicAopProxy(config);      // JDK动态代理
        }
    }

    /**
     * Determine whether the supplied {@link AdvisedSupport} has only the
     * {@link org.springframework.aop.SpringProxy} interface specified
     * (or no proxy interfaces specified at all).
     */
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }

}

2.0.3:getProxy()

就是JDK或者CGILB创建代理对象了。

  • CGLIB代理回调:CglibAopProxy类下的类部类DynamicAdvisedInterceptor
  • JDK代理回调:JdkDynamicAopProxy

到此AOP切面创建代理对象就结束了。


回归到前面提到的this.aspectJAdvisorsBuilder保存了我们所有的切面类,和通知方法。它在什么时候进初始化的.

核心属性

public class BeanFactoryAspectJAdvisorsBuilder {
    /**
     * 当前Spring Bean工厂
     */
    private final ListableBeanFactory beanFactory;

    private final AspectJAdvisorFactory advisorFactory;

    /**
     * @Aspect 标注的类名集合
     */
    @Nullable
    private volatile List<String> aspectBeanNames;

    /**
     * key      @Aspect 标注的类名集合
     * value    @Aspect 下的所有通知方法
     */
    private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
}

参考1.0.3的findCandidateAdvisors();查找所有的切面通知方法。
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()构建。

解释:
会在第一次获取所有通知方法的时候,从容器中拿到所有的Bean name,然后通过BeanName获取Bean的定义信息,在通过反射获取类上是否有@Aspect注解。如果有,反射获取该类中所有有通知方法注解的方法。然后再缓存起来,下次再获取直接走缓存。

public class BeanFactoryAspectJAdvisorsBuilder {
    /**
     * @Aspect 标注的类名集合
     */
    @Nullable
    private volatile List<String> aspectBeanNames;

    /**
     * key      @Aspect 标注的类名集合
     * value    @Aspect 下的所有通知方法
     */
    private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();

    public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;

        /**
         * 第一次进行会等于 null
         */
        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                // 双重检验锁
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    // 从容器中拿到所有的 Bean name
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    for (String beanName : beanNames) {
                        // 检查Bean name是否合格
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // 拿到Bean的类型
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        // 是否切面类 ( 是否有 @Aspect 注解)
                        if (this.advisorFactory.isAspect(beanType)) {
                                // 省略大段代码...
                                // this.aspectBeanNames添加切面类, this.advisorsCache添加通知方法
                            }
                            else {
                                //省略打断代码...
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }
    /**
     * 如果已经有缓存了
     */
        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        List<Advisor> advisors = new ArrayList<>();
        for (String aspectName : aspectNames) {
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        return advisors;
    }
}

开始讲解AOP切面执行流程

流程图,必需了解到各个通知拦截执行顺序。由于递归这种文字描述不太清楚,后面直接看代码
在这里插入图片描述


JDK代理的方法执行器是: ReflectiveMethodInvocation.proceed() CGLIB代理的方法执行器是: CglibMethodInvocation.proceed(),但是 CglibMethodInvocation继承了 ReflectiveMethodInvocation,所以我直接分析 ReflectiveMethodInvocation

ReflectiveMethodInvocation 通知方法执行开始

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    @Override
    @Nullable
    public Object proceed() throws Throwable {
        /**
         * 从-1的索引开始,并提前递增。
         */
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            /**
             * 如果当前 index 自增, 等于拦截方法数组索引
             * 执行目标方法
             */
            return invokeJoinpoint();
        }
        // 获取当前 自增后的索引  第一次也就是 索引0
        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            /**
             * 省略部分代码...
             */
        }
        else {
            /**
             * 开始执行拦截方法 例如 @AfterThrowing, @AfterReturning, @After, @Around, @Before
             *
             * 注意:拦截方法里面会有一个默认的 它并没有做什么工作
             */
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}

return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
这行代码是关键,执行通知方法处理器,注意:这里入参把 this 传进去了

1.0.0:第一步是执行默认的通知方法。

return mi.proceed();,mi是方法入参,查看之前的 invoke(this); mi 就是ReflectiveMethodInvocation实例,它又回调了proceed()方法。

public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {
    private static final ThreadLocal<MethodInvocation> invocation =
            new NamedThreadLocal<>("Current AOP method invocation");
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = invocation.get();
        /**
         * 设置当前线程的通知方法拦截器
         */
        invocation.set(mi);
        try {
            /**
             * 这里它又回调了 proceed() 方法
             */
            return mi.proceed();
        }
        finally {
            invocation.set(oldInvocation);
        }
    }
}

2.0.0:@AfterThrowing异常通知方法执行器

在1.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
它进行捕获了异常,如果回调去执行其他通知方法,发生异常,则执行异常通知方法。

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
        implements MethodInterceptor, AfterAdvice, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            /**
             * 回调 proceed()
             */
            return mi.proceed();
        }
        catch (Throwable ex) {
            /**
             * 如果发生异常,就执行异常通知方法
             */
            if (shouldInvokeOnThrowing(ex)) {
                // 执行异常通知方法     这些是入参
                invokeAdviceMethod(getJoinPointMatch(), null, ex);
            }
            throw ex;
        }
    }
}

3.0.0:@AfterReturning返回通知方法执行器

在2.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
他在回调proceed()拿到返回值后,执行返回通知方法执行器

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        /**
         * 回调去执行通知方法,并拿到结果的返回值
         */
        Object retVal = mi.proceed();
        /**
         * 执行 返回通知方法
         */
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}

4.0.0:@After目标方法执行后通知方法执行器

在3.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
回调proceed(), 它有一个finally 处理,所以无论执行结果是什么,都会执行后置通知方法。

public class AspectJAfterAdvice extends AbstractAspectJAdvice
        implements MethodInterceptor, AfterAdvice, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            /**
             * 回调执行 proceed()
             */
            return mi.proceed();
        }
        finally {
            /**
             * 无论执行结果正常还是异常,都会执行 后置通知方法
             */
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }
    }
}

4.0.0:@Around环绕通知方法执行器

在4.0.0回调了proceed,当前索引再加一后,就是这个通知方法。
会直接执行环绕通知方法,并拿到返回值,结束递归。
注意:我们在环绕通知中执行的 proceedingJoinPoint.proceed() 等同于之前的 mi.proceed()。如果不去调用proceedingJoinPoint.proceed() 就不会执行前置通知方法。

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
    @Override
    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;
        /**
         * 获取环绕通知的 {@link ProceedingJoinPoint} 切入点连接器实例
         */
        ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
        JoinPointMatch jpm = getJoinPointMatch(pmi);
        /**
         * 执行环绕通知方法
         * 如果在环绕通知方法中运行了 ProceedingJoinPoint.proceed();
         * 等同于之前的回调 mi.proceed()
         */
        return invokeAdviceMethod(pjp, jpm, null, null);
    }
}

5.0.0:@Before目标方法执行前通知方法执行器

在4.0.0环绕通知方法中运行了 proceedingJoinPoint.proceed(),就是这个通知方法。
会先执行前置通知方法,在回调。

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        /**
         * 先执行 目标方法执行前通知
         */
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        /**
         * 回调 proceed()
         */
        return mi.proceed();
    }
}

6.0.0:又来到了ReflectiveMethodInvocation.proceed()

因为前置通知方法是数组最后一个,所以会直接去执行目标方法,拿到返回结果,再结束递归,一层一层往上返回。
@Before -> @Around -> @After -> @AfterReturning -> @AfterThrowing

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    @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();
        }
        /**
         * 省略很多代码...
         */
    }
}

AOP的分析到此结束,个人觉得分析得不是很好,请勿喷☺

感兴趣的朋友,可以自己断点去追踪下源码,一步一步看AOP的执行流程,效果会更好。然后照着AOP的通知方法执行流程,自己也手写一个,那肯定是非常棒的。


值得一提:

  • Spring的声明式事务@Transactional也是AOP去实现的。
  • 异步处理@Async也是AOP实现的。
  • AOP代理对象都是通过BeanPostProcessor后置处理器去创建的。
  • AOP在Spring中应用非常多。

下面我分享下,如何自己动手找到Spring AOP在什么时候帮我们创建代理对象的。

先下一个断点在finishBeanFactoryInitialization(beanFactory);
实例化所有剩下的单实例Bean
在这里插入图片描述
再下一步到beanFactory.preInstantiateSingletons();这:实例化所有的单实例Bean
在这里插入图片描述
在循环体里面下一个断点,一直按F9跳过,直到看到我们要创建AOP切面的BeanName
在这里插入图片描述
getBean(BeanName)处下一个断点,因为不管是FactoryBean创建Bean还是注解创建Bean都是执行getBean(BeanName)。
在这里插入图片描述
一直下一步,会执行到 doGetBean,先从已经创建的Bean缓存中查询,一开始肯定没有的。
在这里插入图片描述
再断点往下走,会来到一个匿名内部类中,createBean(beanName), 创建Bean,这里就开始创建Bean了。
在这里插入图片描述
继续断点往下走,会来到 doCreateBean(beanName) 正式的创建Bean实例。
在这里插入图片描述
断点继续往下走,开始帮我们创建实例了。此时已经创建了实例,但类型是我们的原始类型。
在这里插入图片描述
再往下执行到这一行 exposedObject = initializeBean(beanName, exposedObject, mbd);
populateBean(beanName, mbd, instanceWrapper);是为Bean实例的属性赋值的,所以不会创建代理对象的。
在这里插入图片描述

直接下一步操作,唉,Bean实例对象已经变成了CGLIB代理对象了。说明创建代理对象在initializeBean(beanName, exposedObject, mbd);方法里面完成的。
在这里插入图片描述
再来一次断点,进入到 initializeBean(beanName, exposedObject, mbd); 方法中。
invokeAwareMethods如果你的Bean实现了一些Aware接口,就回调执行。
在这里插入图片描述
再下一步:applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
应用所有的BeanPostProcessor后置处理器的前置通知方法。
可以看出。执行到这里之前,Bean实例还是原始类型。

在这里插入图片描述

再下一步走到:invokeInitMethods(beanName, wrappedBean, mbd);执行所以有的初始化方法。
走到这一步的时候,Bean实例还是原始类型。
在这里插入图片描述

再往下走来到:applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 这也是initializeBean(beanName, exposedObject, mbd); 最后一步了。
应用所有的BeanPostProcessor后置处理器的后置通知方法。
在执行此方法之前,Bean实例依然还是原始类型。
在这里插入图片描述

再往下走一步:就变成了 CGLIB代理对象了,说明创建代理对象是在BeanPostProcessor后置处理器的后置通知方法中完成的。

在这里插入图片描述

AOP创建代理对象的后置处理器AnnotationAwareAspectJAutoProxyCreator

再使用@EnableAspectJAutoProxy注解的时候,向容器中导入了这类。

觉得对您有帮助,就点个赞呗。😀
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Me_Liu_Q

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

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

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

打赏作者

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

抵扣说明:

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

余额充值