java之拦截器和适配器模式

什么是拦截器?

拦截器是Spring框架提供的核⼼功能之⼀,主要⽤来拦截⽤⼾的请求,在指定⽅法前后,根据业务需要执⾏预先设定的代码.

也就是说,允许开发⼈员提前预定义⼀些逻辑,在⽤⼾的请求响应前后执⾏.也可以在⽤⼾请求前阻⽌其执⾏.

在拦截器当中,开发⼈员可以在应⽤程序中做⼀些通⽤性的操作,⽐如通过拦截器来拦截前端发来的请求,判断Session中是否有登录⽤⼾的信息.如果有就可以放⾏,如果没有就进⾏拦截.

就⽐如我们去银⾏办理业务,在办理业务前后,就可以加⼀些拦截操作,办理业务之前,先取号,如果带⾝份证了就取号成功。业务办理结束,给业务办理⼈员的服务进⾏评价.这些就是"拦截器"做的⼯作

拦截器的基本使用

拦截器的使⽤步骤分为两步:

  1. 定义拦截器
  2. 注册配置拦截器

自定义拦截器

⾃定义拦截器:实现HandlerInterceptor接⼝,并重写其所有⽅法

package com.example.demo.configuration;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("执行目标方法前的代码");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("目标执行完后的代码");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("目标试图渲染后的代码");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}

这里涉及到的三个方法

preHandle()⽅法:⽬标⽅法执⾏前执⾏. 返回true:继续执⾏后续操作;返回false:中断后续操作.
postHandle()⽅法:⽬标⽅法执⾏后执⾏
afterCompletion()⽅法:视图渲染完毕后执⾏,最后执⾏(后端开发现在⼏乎不涉及视图,暂不了解)

注册配置拦截器

注册配置拦截器:实现WebMvcConfigurer接⼝,并重写addInterceptors⽅法

WebMvcConfigurer这个接口并不是只给拦截器使用的,而是WebMVC相关的配置都在这里

package com.example.demo.configuration;

import com.example.demo.model.LoginInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class WebConfig implements WebMvcConfigurer {

@Autowired

private LoginInterceptor loginInterceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(loginInterceptor)

.addPathPatterns("/**");

}

}

启动服务,试试访问任意请求,观察后端⽇志

wo们把拦截器中preHandle⽅法的返回值改为false,再观察运⾏结果

运行结果:可以看到,拦截器拦截了请求,没有进⾏响应

拦截路径

关于注册配置拦截器的拦截路劲,拦截路径是指我们定义的这个拦截器,对哪些请求⽣效.我们在注册配置拦截器的时候,通过 addPathPatterns() ⽅法指定要拦截哪些请求.也可以通过

excludePathPatterns() 指定不拦截哪些请求.上述代码中,我们配置的是 /** ,表⽰拦截所有的请求.

拦截器中除了可以设置 /** 拦截所有资源外,还有⼀些常⻅拦截路径设置,比如在该项目中

拦截器执行流程

当我们有了拦截器以后,我们的执行流程为

1.添加拦截器后,执⾏Controller的⽅法之前,请求会先被拦截器拦截住.执⾏ preHandle() ⽅法,这个⽅法需要返回⼀个布尔类型的值.如果返回true,就表⽰放⾏本次操作,继续访问controller中的⽅法.如果返回false,则不会放⾏(controller中的⽅法也不会执⾏).

2.controller当中的⽅法执⾏完毕后,再回过来执⾏ postHandle() 这个⽅法以及afterCompletion() ⽅法,执⾏完毕之后,最终给浏览器响应数据.

适配器模式的定义

适配器模式,也叫包装器模式.将⼀个类的接⼝,转换成客⼾期望的另⼀个接⼝,适配器让原本接⼝不兼容的类可以合作⽆间.

简单来说就是⽬标类不能直接使⽤,通过⼀个新类进⾏包装⼀下,适配调⽤⽅使⽤.把两个不兼容的接⼝通过⼀定的⽅式使之兼容.

比如下⾯两个接⼝,本⾝是不兼容的(参数类型不⼀样,参数个数不⼀样等等

适配器模式角色

  • Target:⽬标接⼝(可以是抽象类或接⼝),客⼾希望直接⽤的接⼝
  • Adaptee:适配者,但是与Target不兼容
  • Adapter:适配器类,此模式的核⼼.通过继承或者引⽤适配者的对象,把适配者转为⽬标接⼝
  • client:需要使⽤适配器的对象

适配器模式的实现

场景:前⾯学习的slf4j就使⽤了适配器模式,slf4j提供了⼀系列打印⽇志的api,底层调⽤的是log4j或者 logback来打⽇志,我们作为调⽤者,只需要调⽤slf4j的api就⾏了

Slf4j和Log4j的适配器

客户端调用:

可以看出,我们不需要改变log4j的api,只需要通过适配器转换下,就可以更换⽇志框架,保障系统的平稳 运⾏

适配器模式应用场景

⼀般来说,适配器模式可以看作⼀种"补偿模式",⽤来补救设计上的缺陷.

应⽤这种模式算是"⽆奈之举",如果在设计初期,我们就能协调规避接⼝不兼容的问题,就不需要使⽤适配器模式了

所以适配器模式更多的应⽤场景主要是对正在运⾏的代码进⾏改造,并且希望可以复⽤原有代码实现新的功能.⽐如版本升级等

相关推荐
时空系5 小时前
第3篇:数据的运算——让数据动起来 Rust中文编程
开发语言·后端·rust
Shadow(⊙o⊙)5 小时前
智能指针、循环引用、锁、删除器
开发语言·c++·后端·visual studio
lifewange5 小时前
Claude Code可以安装在IDEA和Pycharm中么
java·pycharm·intellij-idea
lifewange5 小时前
OpenCode可以安装在IDEA和Pycharm中么
java·pycharm·intellij-idea
Sylvia-girl5 小时前
C++模板【上】
开发语言·c++
2zcode5 小时前
基于MATLAB多特征融合与SVM的金属表面缺陷检测系统
开发语言·支持向量机·matlab
2zcode5 小时前
基于MATLAB脑电信号的帕金森病抑郁症检测研究
开发语言·matlab·抑郁症·帕金森病
untE EADO5 小时前
Java进阶之路,Java程序员职业发展规划
java·开发语言
xyq20245 小时前
C++ 变量作用域
开发语言