【Java】Spring-AOP与拦截器实战 (上手图解)

Java系列文章目录

补充内容 Windows通过SSH连接Linux
第一章 Linux基本命令的学习与Linux历史


一、前言

  • 学习Spring-AOP与拦截器
  • 有时候使用AOP时不知道他们的执行顺序与关系

二、学习内容:

  • Spirng-AOP实操
  • 拦截器实操

三、问题描述

  • 学习相关注解

🌟 学习执行顺序


四、解决方案:

4.1 认识依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
  • 引入依赖后可使用Spring-AOP

4.2 使用AOP与拦截器

4.2.1 使用AOP

4.2.1.1 设置DemoAop类
  • 使用@Aspect注解

在这里插入图片描述

4.2.2.2 设置切面

设置切点使用@Pointcut

  • execution(访问修饰符 返回值类型 方法全称)

以下是使用的方法
execution(* com.example.service….(…))
com.example.service. :完整的包路径
com.example.service… :com.example.service下面所有的子孙包
com.example.service…* :com.example.service下面所有的子孙包的所有类
com.example.service…. :com.example.service下面所有的子孙包的所有类的所有方法
com.example.service….(…) :com.example.service下面所有的子孙包的所有类的所有方法,参数打两个点表示任何方法参数(…),即忽略参数

如图所示:
在这里插入图片描述

4.2.2.3 设置方法的切点运行情况
  • @Before:在目标方法之前运行:前置通知
  • @After:在目标方法之后运行:后置通知
  • @AfterReturning:在目标方法正常返回之后:返回通知
  • @AfterThrowing:在目标方法抛出异常后开始运行:异常通知
  • @Around:环绕:环绕通知

在这里插入图片描述
一般对接口进行切面比较方便这里只是举例直接切方法

切点代码如下:

@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping("/index")
    public Result index() {
        System.out.println("这是demoController...");
        return Result.success("success");
    }

    @GetMapping("/error")
    public Result error() {
        System.out.println("这是异常errorController...");
        throw new RuntimeException("模拟异常");
    }
}

设置切面类:

@Aspect
@Component
@Slf4j
public class DemoAop {

    @Autowired
    private HttpServletRequest request;

    //  @Pointcut("execution(* org.example.aoptest.controller.DemoController.index(..))")
    @Pointcut("execution(* org.example.aoptest.controller.*.*(..))")
    public void pt()
    {
        System.out.println("这是pt切面");
    }

    @Before("pt()")
    public void before()
    {
        System.out.println("这是before切面");
    }

    @After("pt()")
    public void after()
    {
        System.out.println("这是after切面");
    }


    @AfterReturning(pointcut = "pt()", returning = "result")
    public void afterReturning(Object result) {
        System.out.println("这是afterReturning切面");
    }

    @AfterThrowing(pointcut = "pt()", throwing = "ex")
    public void afterThrowing(Exception ex) {
        System.out.println("这是afterThrowing切面: " + ex.getMessage());
    }

    @Around("pt()")
    public Object exec(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("这是around切面...before...");

        String token = request.getHeader("Authorization");
        log.info("token:{}",token);

        if (token.equals("1"))
        {
            Object process = pjp.proceed();
            return process;
        }


        System.out.println("这是around切面...after...");
        return Result.error();
    }

}

4.2.2 使用拦截器

拦截器详细的之后总结,我们主要观察AOP与拦截器的顺序

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private DemoInterceptor demoInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        System.out.println("==========");
        System.out.println(demoInterceptor);
        System.out.println("==========");

        registry.addInterceptor(demoInterceptor).addPathPatterns("/**");


    }
}
  • WebMvcConfigurer 是 Spring MVC 中的一个接口,用于定制 Web MVC的功能,如添加拦截器、视图解析器、配置静态资源等。实现该接口可以按需调整框架行为,优化 Web 层的功能而不必直接修改默认设置。
@Component
public class DemoInterceptor implements HandlerInterceptor {

    public DemoInterceptor(){
        System.out.println("=========================");
        System.out.println(this);
        System.out.println("=========================");
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle被调用...");
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle被调用...");
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

}
  • HandlerInterceptor 是 Spring框架中的一个接口,它定义了请求处理的拦截器。实现该接口可以创建自定义的拦截器类

  • 测试的时候要加上请求头

在这里插入图片描述

4.2.3 测试结果与总结

4.2.3.1 观察内容

观察图片区别

  • AOP类里面我们获取请求头是Authorization的数据
    在这里插入图片描述

ProceedingJoinPoint

  • 这是AspectJ框架中的一个接口,代表程序执行过程中的一个连接点(如方法调用)。它提供了对目标方法的调用控制以及访问方法签名、参数等功能的方法。

exec

  • 方法名称,开发者自定义的方法名,用于执行围绕通知逻辑。

pjp.proceed()

  • 是 AspectJ 中 ProceedingJoinPoint 接口的一个方法,用于执行被拦截的目标方法。

具体说明如下:

  • 此方法会调用被环绕(around advice)的方法。在执行了前置操作之后,通过调用
    proceed()来触发原始方法的执行,并在方法完成后执行后续的操作(如后置通知)。
4.2.3.2 观察结果
  • 请求头正确且token正确

token为1:
在这里插入图片描述

  • 请求头正确但token错误

这个可以看出如果不能进入方法那么@Before@After也不能执行

token为2:
在这里插入图片描述

  • 请求头错误

在这里插入图片描述

  • error方法测试

在这里插入图片描述

4.2.3.2 现象总结

🌟 很明显方法与Before与After是一体的
🌟 其中@AfterThrow@AfterReturning是在方法执行后出现的优先级比@Before@After

在这里插入图片描述


五、总结:

🌟 很明显方法与Before与After是一体的
🌟 其中@AfterThrow@AfterReturning是在方法执行后出现的,优先级比@Before@After

  • 日志记录:在方法执行前后自动记录日志。
  • 事务管理:自动处理数据库事务的开始、提交和回滚。
  • 权限控制:在方法执行前进行权限验证。
  • 性能监控:记录方法执行时间和调用频率等性能指标。
  • 缓存策略:限定条件下缓存方法返回结果,提高性能。

(后续有遇到问题再添加)


声明:如本内容中存在错误或不准确之处,欢迎指正。转载时请注明原作者信息(麻辣香蝈蝈)。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值