[springboot——01] AOP方式管理

目录

1.引入依赖 

2.创建增强类

3.写我们的被增强类

4.运行我们的程序,访问 /aoptest

5.应用场景


AOP 概念

  • 切入点 pointcut
  • 通知 advice
  • 切面 aspect = 切入点 + 通知
  • 织入 weaving 将切面加入对象,并创建出代理对象的过程
  • 环绕通知 【最强大、灵活的通知】

1.引入依赖 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.创建增强类

execution 表达式相关文章:AOP(execution表达式)

package com.example.demo.aop;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author: fly
 * @Date: 2023-03-19 14:50
 * @Description: 切面类
 */
@Aspect
@Component
@Log4j2
public class AopLog {
    // 线程局部的变量,用于解决多线程中相同变量的访问冲突问题
    ThreadLocal<Long> startTime = new ThreadLocal<>();

    // 定义切点 com.example.demo 下面的当前包和子包下面的所有类中的所有方法
    // @Pointcut("execution(* com.example.demo..*.*(..))")
    // 针对 controller 层的 AopLog 类的 aopTest方法进行测试
    @Pointcut("execution(String com.example.demo.controller.AopLogController.aopTest())")
    public void aopWebLog() {}

    // 前置通知
    @Before("aopWebLog()")
    public void doBefore(JoinPoint joinPoint) {
        // 记录开始时间
        startTime.set(System.currentTimeMillis());
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        log.info("URL: " + request.getRequestURL().toString());
        log.info("HTTP方法: " + request.getMethod());
        log.info("IP地址: " + request.getRemoteAddr());
        log.info("类的方法: " + joinPoint.getSignature().getDeclaringTypeName() + "." +
                joinPoint.getSignature().getName());
        log.info("参数: " + request.getQueryString());
    }

    // 方法抛出异常退出时执行的通知
    @AfterThrowing(pointcut = "aopWebLog()",throwing = "exception")
    public void addAfterThrowingLog(JoinPoint joinPoint,Exception exception) {
        log.error("执行 " + "异常",exception);
    }
}

 拓展知识:通知的分类

  1. @Before 前置通知
  2. @AfterReturning 后置通知
  3. @After 最终通知
  4. @AfterThrowing 异常通知
  5. @Around 环绕通知 【与上面的通知的写法稍微有点区别
public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("[增强类]环绕通知前...");
        pjp.proceed();
        System.out.println("[增强类]环绕通知后...");
}

3.写我们的被增强类

 根据切入点,我们可以定位到 被增强类

@Pointcut("execution(String com.example.demo.controller.AopLogController.aopTest())")
@RestController
public class AopLogController {
    @RequestMapping("/aoptest")
    public String aopTest() {
        return "hello aop test!";
    }
}

4.运行我们的程序,访问 /aoptest

 

5.应用场景

  1.  将重复代码进行抽取,即代码简化
  2.  增加特定性功能,即代码增强

拓展资料:

  1. AOP —— 代码重工
  2. AOP(execution表达式)
  3. 谈谈你对IOC和AOP的理解及AOP四种实现方式

猜你喜欢

转载自blog.csdn.net/qq_56402474/article/details/129650921
今日推荐