Spring Boot AOP源码

一、时序图

spring AOP时序图,描述代理对象生成及拦截器执行流程。由于图片过大,此处不做截图展示。
git地址有详细时序图,有相应的html文件可以直接浏览
地址: https://github.com/13162576590/spring-source-study

二、Spring AOP

​ AOP 是 OOP 的延续,是 Aspect Oriented Programming 的缩写,意思是面向切面编程。可以通过预 编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP 设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP 可以说也是这种目标的一种实现。 我们现在做的一些非业务,如:日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切 于业务类),但这些代码往往是重复,复制——粘贴式的代码会给程序的维护带来不便,AOP 就实现了 把这些业务需求与系统需求分开来做。这种解决的方式也称代理机制。

​ Spring 的 AOP 是通过接入 BeanPostProcessor 后置处理器开始的,它是 Spring IOC 容器经常使用到 的一个特性,这个 Bean 后置处理器是一个监听器,可以监听容器触发的 Bean 声明周期事件。后置处 理器向容器注册以后,容器中管理的 Bean 就具备了接收 IOC 容器事件回调的能力。

​ initializeBean()方法为容器产生的 Bean 实例对象添加 BeanPostProcessor 后置处理器,AbstractAutowireCapableBeanFactory 类中,initializeBean()方法实现为容器创建的 Bean 实例对象添加 BeanPostProcessor 后置处理器。该方法就是spring AOP的入口。

进入AbstractAutowireCapableBeanFactory类protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)方法
  exposedObject = initializeBean(beanName, exposedObject, mbd);
	继续调用AbstractAutowireCapableBeanFactory类方法
	1public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException 方法
  //调用 BeanPostProcessor 后置处理器实例对象初始化之前的处理方法
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
  public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
  throws BeansException {
    Object result = existingBean;
    //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      //调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在初始化之前做一些自定义的处理操作
      Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); 
      if (current == null) {
        return result;
      }
      result = current; 
    }
    return result;
  }
	2public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException方法
    //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    //调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
         throws BeansException {
        Object result = existingBean;
        //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
          //调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在初始化之后做一些自定义的处理操作
          Object current = beanProcessor.postProcessAfterInitialization(result, beanName); 
          if (current == null) {
              return result;
           }
          result = current; 
        }
    		return result;
    }

BeanPostProcessor是一个接口,其初始化前的操作方法和初始化后的操作方法均委托其实现子类来实现,在Spring中,BeanPostProcessor的实现子类非常的多,分别完成不同的操作,如:AOP面向切面编程的注册通知适配器、Bean对象的数据校验、Bean继承属性、方法的合并等,我们以最简单的AOP切面织入来简单了解其主要的功能。下面我们来分析其中一个创建AOP代理对象的子类AbstractAutoProxyCreator类。该类重写了 postProcessAfterInitialization()方法。
  进入AbstractAutoProxyCreator类public Object postProcessAfterInitialization(@Nullable Object bean, String beanName)方法
  Object current = processor.postProcessAfterInitialization(result, beanName);
	继续调用AbstractAutoProxyCreator类方法
  1protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)方法
    return wrapIfNecessary(bean, beanName, cacheKey);

进入AspectJAwareAdvisorAutoProxyCreator类protected boolean shouldSkip(Class<?> beanClass, String beanName)方法
  if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName))

进入AnnotationAwareAspectJAutoProxyCreator类protected List<Advisor> findCandidateAdvisors()方法
  List<Advisor> candidateAdvisors = findCandidateAdvisors();

进入AbstractAdvisorAutoProxyCreator类protected List<Advisor> findCandidateAdvisors()方法
  List<Advisor> advisors = super.findCandidateAdvisors();

进入BeanFactoryAspectJAdvisorsBuilder类public List<Advisor> buildAspectJAdvisors()方法
  advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());

回到AbstractAutoProxyCreator类public Object postProcessAfterInitialization(@Nullable Object bean, String beanName)方法,继续调用
  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

再次进入AbstractAdvisorAutoProxyCreator类,调用protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)方法
  继续调用AbstractAdvisorAutoProxyCreator类方法
  1protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName)方法

进入AopUtils类public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) 方法
  return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);

再次回到AbstractAutoProxyCreator类protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)方法,继续调用protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource)方法方法
  Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
	继续调用AbstractAutoProxyCreator类方法
  1protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors)方法
    //封装成 Advisor 
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

进入DefaultAdvisorAdapterRegistry类public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException 方法
  advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));

再次回到AbstractAutoProxyCreator类protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource)方法,继续调用public Object getProxy(@Nullable ClassLoader classLoader)方法
  return proxyFactory.getProxy(getProxyClassLoader());

进入ProxyFactory类public Object getProxy(@Nullable ClassLoader classLoader)方法
  return proxyFactory.getProxy(getProxyClassLoader());

进入ProxyCreatorSupport类protected final synchronized AopProxy createAopProxy()方法
  return createAopProxy().getProxy(classLoader);

进入DefaultAopProxyFactory类public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException方法
  return getAopProxyFactory().createAopProxy(this);
	代理2种实现方式:
    1.jdk动态代理
    2.cglib代理
  spring5及spring boot2.x AOP默认是cglib。此处使用cglib代理。
    
回到ProxyFactory类public Object getProxy(@Nullable ClassLoader classLoader)方法,进入CglibAopProxy类public Object getProxy(@Nullable ClassLoader classLoader)方法
    return createAopProxy().getProxy(classLoader);
	继续调用CglibAopProxy类方法
	1private Callback[] getCallbacks(Class<?> rootClass) throws Exception方法
    Callback[] callbacks = getCallbacks(rootClass);

进入ObjenesisCglibAopProxy类protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks)方法
  return createProxyClassAndInstance(enhancer, callbacks);

进入Enhancer类public Class createClass()方法
  Class<?> proxyClass = enhancer.createClass();
	继续调用Enhancer类方法
  1private Object createHelper()方法
    return (Class) createHelper();

进入AbstractClassGenerator类protected Object create(Object key)方法
  Object result = super.create(key);
	继续调用AbstractClassGenerator类方法
  1public Object get(AbstractClassGenerator gen, boolean useCache)方法			
    Object obj = data.get(this, getUseCache());

进入LoadingCache类public V get(K key)方法
  Object cachedValue = generatedClasses.get(gen);
	继续调用LoadingCache类方法
  1protected V createEntry(final K key, KK cacheKey, Object v)方法
    return v != null && !(v instanceof FutureTask) ? v : this.createEntry(key, cacheKey, v);
		源码:
    protected V createEntry(final K key, KK cacheKey, Object v) {
        boolean creator = false;
        FutureTask task;
        Object result;
        if (v != null) {
            task = (FutureTask)v;
        } else {
            task = new FutureTask(new Callable<V>() {
                public V call() throws Exception {
                  	//执行线程方法
                    return LoadingCache.this.loader.apply(key);
                }
            });
            result = this.map.putIfAbsent(cacheKey, task);
            if (result == null) {
                creator = true;
              	//启动一个线程,调用run方法,在run方法内部在回调call()方法,即上述源码return LoadingCache.this.loader.apply(key)处
                task.run();
            } else {
                if (!(result instanceof FutureTask)) {
                    return result;
                }

                task = (FutureTask)result;
            }
        }

        try {
            result = task.get();
        } catch (InterruptedException var9) {
            throw new IllegalStateException("Interrupted while loading cache item", var9);
        } catch (ExecutionException var10) {
            Throwable cause = var10.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException)cause;
            }

            throw new IllegalStateException("Unable to load cache item", cause);
        }

        if (creator) {
            this.map.put(cacheKey, result);
        }

        return result;
    }
		上述源码启动一个线程,调用run方法,在run方法内部在回调call()方法,即上述源码return LoadingCache.this.loader.apply(key)处,然后进入AbstractClassGenerator类内部类ClassLoaderData的构造函数public ClassLoaderData(ClassLoader classLoader)。
		
进入AbstractClassGenerator类内部类ClassLoaderData的public ClassLoaderData(ClassLoader classLoader)构造函数
		return LoadingCache.this.loader.apply(key);
		此处调用是初始化时的一个function接口,源码如下:        
    public ClassLoaderData(ClassLoader classLoader) {
        if (classLoader == null) {
          	throw new IllegalArgumentException("classLoader == null is not yet supported");
        } else {
            this.classLoader = new WeakReference(classLoader);
          	//function接口
            Function<AbstractClassGenerator, Object> load = new Function<AbstractClassGenerator, Object>() {
              public Object apply(AbstractClassGenerator gen) {
                Class klass = gen.generate(ClassLoaderData.this);
                return gen.wrapCachedClass(klass);
              }
            };
          	this.generatedClasses = new LoadingCache(GET_KEY, load);
        }
    }
		当在类LoadingCache的protected V createEntry(final K key, KK cacheKey, Object v)方法调用task.run()方法时,会启动一个线程,最终回调到线程的public V call() throws Exception方法,执行LoadingCache.this.loader.apply(key),因此执行到初始化的function接口。

再次进入Enhancer类,调用protected Class generate(ClassLoaderData data)方法
  	Class klass = gen.generate(ClassLoaderData.this);

再次进入AbstractClassGenerator类,调用protected Class generate(ClassLoaderData data)方法
  	return super.generate(data);

进入ClassLoaderAwareGeneratorStrategy类public byte[] generate(ClassGenerator cg) throws Exception方法
  public byte[] generate(ClassGenerator cg) throws Exception
  
进入DefaultGeneratorStrategy类public byte[] generate(ClassGenerator cg) throws Exception方法
  return super.generate(cg);

再次进入Enhancer类,调用public void generateClass(ClassVisitor v) throws Exception方法
  this.transform(cg).generateClass(cw);
	继续调用Enhancer类方法
	1private void emitMethods(final ClassEmitter ce, List methods, List actualMethods)方法
    emitMethods(e, methods, actualMethods);

再次CglibAopProxy类,调用public int accept(Method method)方法
  int index = filter.accept(actualMethod);

进入AdvisedSupport类public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass)方法
  List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

进入DefaultAdvisorChainFactory类public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass)方法
  cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
  this, method, targetClass);

进入DefaultAdvisorAdapterRegistry类public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException方法
  MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

cglib执行过程,执行入口在CglibAopProxy内部类DynamicAdvisedInterceptor类public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable方法
  
再次进入AdvisedSupport类	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass)方法
  // 获取当前方法的拦截器链
  List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

进入CglibAopProxy类public Object proceed() throws Throwable方法
  retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

进入ReflectiveMethodInvocation类public Object proceed() throws Throwable方法
  return super.proceed();
	源码如下:
  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类public Object invoke(MethodInvocation mi) throws Throwable方法
  return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	ExposeInvocationInterceptor暴露调用器的拦截器,其就是起了暴露一个调用器作用的拦截器。
    
进入CglibAopProxy内部类CglibMethodInvocation的public Object proceed() throws Throwable方法
  return mi.proceed();

再次回到ReflectiveMethodInvocation类public Object proceed() throws Throwable方法
  //CglibMethodInvocation#proceed
  return super.proceed();

进入AspectJAroundAdvice类public Object invoke(MethodInvocation mi) throws Throwable方法
  //根据不同的拦截器,进入不同的类
  return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

进入AbstractAspectJAdvice类方法protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,@Nullable Object returnValue, @Nullable Throwable t) throws Throwable方法
  return invokeAdviceMethod(pjp, jpm, null, null);
	继续调用AbstractAspectJAdvice类方法
  1return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t))方法
    return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));

进入Method类public Object invoke(Object obj, Object... args)方法
  return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);

进入DelegatingMethodAccessorImpl类public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException方法
  return ma.invoke(obj, args);

进入NativeMethodAccessorImpl类public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException方法
  return this.delegate.invoke(var1, var2);

进入切面方法,Demo是以LogAspect为列,故进入LogAspect类public Object doAround(ProceedingJoinPoint point) throws Throwable方法
  return invoke0(this.method, var1, var2);
  LogAspect类源码如下:
  /**
   * 项目名称:spring-cloud-service
   * 类 名 称:LogAspect
   * 类 描 述:TODO
   * 创建时间:2020/9/12 11:06 下午
   * 创 建 人:chenyouhong
   */
  @Aspect
  @Component
  public class LogAspect {

      @Pointcut("execution(* com.cloud.user.controller.*.*(..))")
      public void aspect() {
      }

      @Before("aspect()")
      public void before(JoinPoint jp) throws Throwable {
          //...
          System.out.println("Before");
      }


      @Around("aspect()")
      public Object doAround(ProceedingJoinPoint point) throws Throwable {
          //...
          System.out.println("==========");
          Object returnValue =  point.proceed(point.getArgs());
          System.out.println("**********");
          //...
          return returnValue;
      }

      @After("aspect()")
      public void after(JoinPoint jp) throws Throwable {
          //...
          System.out.println("after");
      }
  }

	此处会进入切面LogAspect类public Object doAround(ProceedingJoinPoint point) throws Throwable方法
  
进入MethodInvocationProceedingJoinPoint类public Object proceed(Object[] arguments) throws Throwable方法
  Object returnValue =  point.proceed(point.getArgs());

再次回到ReflectiveMethodInvocation类public Object proceed() throws Throwable方法
  //CglibMethodInvocation#proceed
  return super.proceed();

进入MethodBeforeAdviceInterceptor类public Object invoke(MethodInvocation mi) throws Throwable方法
  return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	因为此时的拦截器interceptorOrInterceptionAdvice对应的类型是MethodBeforeAdviceInterceptor。

进入AspectJMethodBeforeAdvice类public void before(Method method, Object[] args, @Nullable Object target) throws Throwable方法
  this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());

再次进入AbstractAspectJAdvice类方法protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,@Nullable Object returnValue, @Nullable Throwable t) throws Throwable方法
  return invokeAdviceMethod(pjp, jpm, null, null);
	继续调用AbstractAspectJAdvice类方法
  1return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t))方法
    return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
	  此处逻辑同上述invokeAdviceMethod方法执行一直,只是执行切面时,进入方法是LogAspect类public void before(JoinPoint jp) throws Throwable方法

再次回到CglibAopProxy内部类CglibMethodInvocation的public Object proceed() throws Throwable方法
  return mi.proceed();
	继续执行,当执行到拦截器,因为此时的拦截器interceptorOrInterceptionAdvice对应的类型是AspectJAfterAdvice。
    
进入AspectJAfterAdvice类public Object invoke(MethodInvocation mi) throws Throwable方法
  //interceptorOrInterceptionAdvice类型是AspectJAfterAdvice
  return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    
当执行到最后一个拦截器时,进入CglibAopProxy内部类CglibMethodInvocation的protected Object invokeJoinpoint() throws Throwable方法
  return invokeJoinpoint();
	
  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    return invokeJoinpoint();
  }

进入MethodProxy类public Object invoke(Object obj, Object[] args) throws Throwable方法
  return this.methodProxy.invoke(this.target, this.arguments);
	继续调用MethodProxy类方法
  1init()方法
  
进入被代理类需要执行的方法,demo是UserController类public Mono<String> login()方法
  return fci.f1.invoke(fci.i1, obj, args);
	被代理类源码如下:
  @RestController
  @RequestMapping("/user")
  public class UserController {

      @Autowired
      private TestService testService;

      private List<String> list;

      /**
       * 密码模式  认证.
       *
       * @return
       */
      @RequestMapping("/test")
      public Mono<String> login() {
          //登录 之后生成令牌的数据返回

          testService.test();
          return Mono.just("test");
      }

      /**
       * 密码模式  认证.
       *
       * @return
       */
      @RequestMapping("/test2")
      @PreAuthorize(value = "hasAnyAuthority('test')")
  //    @PreAuthorize("hasPermission('test8988989')")
      public Mono<String> login2() {
          //登录 之后生成令牌的数据返回
          System.out.println("rest2");
          return Mono.just("test2");
      }
  }

再次回到AspectJAfterAdvice类public Object invoke(MethodInvocation mi) throws Throwable方法
  继续之前并未执行完逻辑,继续往后执行,源码如下:
  @Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
      //执行被代理类想要执行的方法
			return mi.proceed();
		}
		finally {
      //此处逻辑同上述invokeAdviceMethod方法执行一直,只是执行切面时,进入方法是LogAspect类public void after(JoinPoint jp) throws Throwable方法
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值