一、Spring AOP
AOP(Aspect Oriented Programming) 是一种面向切面的编程思想。面向切面编程是将程序抽象成各个切面,即解剖对象的内部,将那些影响了多个类的公共行为抽取到一个可重用模块里,减少系统的重复代码,降低模块间的耦合度,增强代码的可操作性和可维护性。
其中的核心概念:
| 名称 | 说明 | 
| Joinpoint(连接点) | 指那些被拦截的点,在spring中,指可以被动态代理拦截目标类的方法 | 
| Pointcut(切入点) | 指要对哪些 Jointpoint 进行拦截,即被拦截的连接点 | 
| Advice(通知) | 指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容 | 
| Target(目标) | 指代理的目标对象 | 
| Weaving(植入) | 指把增强代码应用到目标上,生成代理对象的过程 | 
| Proxy(代理) | 指生成的代理对象 | 
| Aspect(切面) | 切入点和通知的结合 | 
二、AOP的使用场景
AOP可以拦截指定的方法,并且对方法增强,比如:事务、日志、权限、性能监测等增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离。
三、AOP的通知分类以及代码示例
1、通知的分类
 
   2、代码示例
(1)pom.xml中导入依赖
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>(2)新建配置类LogAspectConfig,使用 @Component、@Aspect 定义切面,@Pointcut定义切点
@Component
@Aspect
public class LogAspectConfig {
    // 匹配指定包中的所有方法
    //execution(* org.example.service.*(..))
    // 匹配当前包中的所有public方法
    //execution(public * UserService.*(..))
    // 匹配指定包中的所有public方法,并且返回值是int类型的方法
    //execution(public int org.example.service.*(..))
    // 切点
    @Pointcut("execution(* org.example.controller.*.*(..))")
    public void operationLog(){};
    /**
     * 方法执行前调用
     * @param joinPoint
     */
    @Before("operationLog()")
    public void TestBefore(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("即将调用该方法:" + methodName);
    }
    /**
     * 方法调用后执行
     * @param joinPoint
     */
    @After("operationLog()")
    public void afterHandler(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        String name = joinPoint.getSignature().getName();
        System.out.println("入参:" + Arrays.asList(args).toString() + ",调用方法名称:" + name);
        System.out.println("调用方法之后");
    }
    /**
     * 调用方法并正常返回后执行
     */
    @AfterReturning("operationLog()")
    public void afterReturningHandler() {
        System.out.println("调用方法并正常返回后执行");
    }
    /**
     * 调用方法却抛出异常后执行
     */
    @AfterThrowing("operationLog()")
    public void afterThrowingHandler() {
        System.out.println("调用方法却抛出异常后执行");
    }
    /**
     * 环绕增强,能控制切点执行前,执行后
     * @param joinPoint
     * @return
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object proceed = null;
        try {
            System.out.println("方法执行前");
            proceed = joinPoint.proceed();
            System.out.println("方法执行后");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}(3)创建CommonController
@RestController
@RequestMapping("/text")
public class CommonController {
    @GetMapping("/query/{id}")
    public String query(@PathVariable int id) {
        if ( 1 == id ) {
            return "李四";
        }
        return "张三";
    }
}(4)postman请求该URL
GET请求: http://192.168.11.7:27100/text/query/1
返回结果:
方法执行前
即将调用该方法:query
方法执行后
入参:[1],调用方法名称:query
调用方法之后
调用方法并正常返回后执行 
   







![[Java Web]Request对象 | 超1w字带你熟悉Servlet中的request请求](https://img-blog.csdnimg.cn/img_convert/73a374ed38b929bc7e19240db36882b7.png)










