springboot aop源码解析

想必大家都知道, springboot  IOC中的bean对象是通过后置处理器转化为代理对象的, 接下来我们通过源码来分析一下这个流程, 及aop使用责任链的设计模式完成4种通知的调用


1. 创建一个springboot项目

项目地址 : 

aop-project: springboot-aop源码解析https://gitee.com/hctrl/aop-project项目目录 : 

springboot aop源码解析_第1张图片

 AopAnno : 

package com.hctrl.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author hctrl
 * @date 2022/1/5 21:12
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AopAnno {

	String value() default "";
}

AopAspect : 

package com.hctrl.aop.aspect;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author hctrl
 * @date 2022/1/5 21:15
 */
@Aspect
@Component
public class AopAspect {

	@Pointcut(value = "@annotation(com.hctrl.aop.annotation.AopAnno)")
	public void access() {}


	@Before("access()")
    public void before(){
		System.out.println("前置通知");
	}

	@After("access()")
	public void after(){
		System.out.println("后置通知");
	}

	@AfterReturning("access()")
	public void afterReturning(){
		System.out.println("返回通知");
	}

	@AfterThrowing("access()")
	public void afterThrowing(){
		System.out.println("异常通知通知");
	}


}

OrderController : 

package com.hctrl.aop.controller;

import com.hctrl.aop.annotation.AopAnno;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author hctrl
 * @date 2022/1/5 21:10
 */
@RestController
@RequestMapping("/v1/order")
public class OrderController {

	@RequestMapping("/create")
	@AopAnno
	public String createOrder(){

		return "创建订单成功";
	}
}

2. 源码分析

question : 后置处理器是什么时候被注入的 ? 

想要弄清这个问题, 首先需要查看大名鼎鼎的refresh()方法,

springboot aop源码解析_第2张图片

 springboot aop源码解析_第3张图片

springboot aop源码解析_第4张图片 

question : bean对象转化为代理对象是什么时候发生的? 是在我们获取bean对象时候才转化为代理对象还是项目启动时就转变成代理对象 ? 

带着这个疑问, 继续向下看源码, 还是在refresh()方法中

springboot aop源码解析_第5张图片

 springboot aop源码解析_第6张图片

 springboot aop源码解析_第7张图片

springboot aop源码解析_第8张图片 springboot aop源码解析_第9张图片

 springboot aop源码解析_第10张图片

 springboot aop源码解析_第11张图片

 springboot aop源码解析_第12张图片

 springboot aop源码解析_第13张图片

 查看AnnotationAwareAspectJAutoProxyCreator类的继承关系

springboot aop源码解析_第14张图片

 springboot aop源码解析_第15张图片

 springboot aop源码解析_第16张图片

springboot aop源码解析_第17张图片 springboot aop源码解析_第18张图片

question : aop目标方法, 前置通知,后置通知, 返回通知,异常通知的调用顺序是如何实现的?

本质上就是通过责任链模式来完成的

我们调用一个代理对象的方法, 通过断点来查看一下 (以cglib代理举例)\

springboot aop源码解析_第19张图片

 我们知道, 调用cglib代理对象的方法, 最终会执行实现了MethodInterceptor类的intercept方法

通过查看博客知道, 最终会执行到CglibAopProxy类中的内部类DynamicAdvisedInterceptor的intercept方法, 打一个断点

springboot aop源码解析_第20张图片

 springboot aop源码解析_第21张图片

 springboot aop源码解析_第22张图片

 aop原理分析结束

你可能感兴趣的:(spring,boot,spring,boot,spring,java)