生命周期内的拦截过滤与监听
ycshang Lv1

一、Servlet域对象与属性变化监听

  • servlet监听器有几类:域对象的创建、销毁属性发生变化
    • ServletContext
    • HttpSession
    • ServletRequest
  • 监听器使用了设计模式种的什么模式?
    • 观察者模式
    • 关注特定事务的创建、销毁以及变化并做出回调动作——>异步
  • 监听器的主要接口
    • image
      • ServletContextListener
      • HttpSessionListener
      • ServletRequestListener
  • 使用场景
    • 系统启动,初始化信息
    • 统计在线用户
    • 统计网站访问量
  • 监听器具体实现
    • 实现ServletContextListener, HttpSessionListener, ServletRequestListener, ServletRequestAttributeListener, HttpSessionAttributeListener接口,并重写方法
    • 在启动类@ServletComponentScan进行自动注册
  • 监听器测试
    • 上下文初始化
    • 请求初始化
    • 会话初始化
    • 属性变化
    • 请求销毁
    • 上下文销毁
    • session的销毁是由Servlet容器根据session超时时间等因素来控制
  • 作用域生命周期
    • ServletContext->HttpSession->ServletRequest

二、过滤器和监听器的实现

  • 过滤器
    • Servlet过滤器是可用于Servlet编程Java类
    • 目的
      • 在客户端的请求访问后端资源之前,拦截这些请求
      • 在服务器的响应发送回客户端之前,处理这些响应
    • 使用场景
      • 授权逻辑
      • IP黑名单
      • 对经过加密的HTTP请求数据,进行统一解密
      • 敏感词过滤
    • 特点
      • 可以过滤所有的请求
      • 能够改变请求的数据内容
    • 实现
      • 利用WebFilter注解配置过滤器
      • FilterRegistraionBean方式注册过滤器

三、Spring拦截器及请求链路说明

  • 拦截器Interceptor
    • 只有Spring才有
    • image
  • 拦截器实现
    • 实现HandlerInterceptorj接口
    • 实现WebMvcConfigurer接口完成拦截器的注册
  • 拦截器与过滤器的核心区别
    • image
    • 规范不同
    • 拦截器可以获取并使用Spring IoC容器中的bean
    • 拦截器可以访问Spring上下文中的对象
    • 拦截粒度:
      • 过滤器比拦截器的粒度更大
        • 适合系统级别的API的处理动作
        • Spring Security大量使用了过滤器
      • 拦截器粒度小,适合分模块、分范围来进行统一业务逻辑处理;分模块记录日志
  • 拦截器实现统一访问日志
    • 需求:
      • 针对当前系统的每一次接口访问,要记录是什么人访问(用户名)、什么时间访问、访问耗时多长时间、使用什么HTTP method方法访问的、访问结果如何等,称为审计日志
    • 日志输出
      • 控制台
      • 输出一个单独的日志文件
      • 持久化
    • 实现步骤
      • 定义一个日志访问内容的实体类
      • 自定义一个日志拦截器
        • preHandle:用户名、startTime、method
      • 拦截器注册
  • 请求链路说明
    • image
      • CustomFilter:customFilter 请求处理之前
      • CustomHandlerInterceptor:preHandle请求前调用
      • CustomHandlerInterceptor:postHandler请求后调用
      • CustomHandlerInterceptor:afterCompletion:请求调用完成后回调方法,在视图渲染完成后回调
      • CustomFilter:customFilter 请求处理之后———doFilter之后处理响应

四、自定义事件的发布与监听

  • 事件监听介绍
    • 事件发布者(事件源)
    • 事件监听者
    • 事件本身
  • 事件监听的特点
    • 异步
    • 解耦
    • 不规律性
  • 事件监听的实现机制
    • 消息队列,中间件->发布订阅模式
    • JDK自带的:Java.util.EventListener
    • Spring环境下的实现的事件发布监听方法
  • 具体实现
    • 自定义事件
    • 定义事件监听器
      • 写代码向ApplicationContext中添加监听器
      • 使用Component注解将监听器装在入spring容器
      • 在application.properties中配置监听器
      • 通过@EventListener注解实现事件监听

五、应用启动监听

  • SpringBoot提供了两个接口,CommandLineRunner、ApplicationRunner用于启动应用时做特殊处理,这些代码会在SpringApplication的run()方法完成之前被执行
  • 常用场景介绍
    • 将系统常用的数据加载到内存
    • 应用上一次运行的垃圾数据清理
    • 系统启动成功后的通知的发送
  • 代码实现
    • 通过@Component定义方式实现
      • CommandLineRunner参数是字符串数组
    • ApplicationRunner:参数被放入ApplicationArguments,通过getOptionsNames()、getOptionValues()、getSourceArgs()获取参数
  • CommandLineRunner和ApplicationRunner两种不同配置的运行顺序【在启动配置中加入参数,保存后启动应用】
    • 运行效果截图
      • ApplicationRunner执行优先级高于CommandLineRunner
      • 以Bean的形式运行的Runner优先级要低于Component注解加implements Runner接口的方式
      • Order注解只能保证同类的CommandLineRunner或ApplicationRunner的执行顺序,不能跨类保证顺序
  • 总结
    • CommandLineRunner、ApplicationRunner的核心用法时一致的,就是用于应用前的特殊代码执行
    • ApplicationRunner的执行顺序先于CommandLineRunner
    • ApplicationRunner将参数封装成对象、提供了获取参数名、参数值等方法、操作上会方便一些

六、类初始化监听

  • 一些初始化动作,要在bean进行初始化的时候进行,而非应用初始化的时候进行
 Comments