tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 探索SpringBoot

  • 常用功能实现

    • SpringBoot常用功能实现_1
    • SpringBoot中拦截器与日志
      • 实现拦截器Interceptor
        • 实现拦截器
        • 拦截器Interceptor和过滤器Filter
      • 日志实现
        • 默认情况
        • 开发使用
        • 修改输出级别跟样式
        • 重写配置文件
    • 多环境配置与数据绑定
    • 异步方法(线程池)的实现
    • controller参数接收
    • SpringBoot中关于日志的更好使用
    • 异常捕获的一些细节
    • 时间跟其他数据的序列化
    • 面向切面跟自定义注解的结合
  • Security认证授权

  • 扩展

  • 实战与注意事项

  • 其它

  • 《SpringBoot》笔记
  • 常用功能实现
EffectTang
2023-11-17
目录

SpringBoot中拦截器与日志

# SpringBoot中拦截器与日志

# 实现拦截器Interceptor

一般流程:

  • 实现 HandlerInterceptor 重写里面的三个方法 preHandle 、postHandle、afterCompletion
  • 最后将自定义的拦截器注入到容器中

其中preHandle方法在请求处理之前会被调用,postHandle方法在当前请求处理完成之后,也就是 Controller 方法调用之后执行,afterCompletion方法在整个请求结束后执行(前两个方法执行完后),且必须 preHandle 方法返回值为 true 时才会执行,主要用来进行资源清理或释放。

# 实现拦截器

@Component
public class IntercepterConfig implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		
        System.out.println("拦截每个请求 都会打印");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        System.out.println("after all is over");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

将其注入到容器中

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private IntercepterConfig intercepterConfig;
	@Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(intercepterConfig);
    }
}
1
2
3
4
5
6
7
8
9
10

在注入的时候,在SpringBoot低一些的版本中使用继承WebMvcConfigurerAdapter ,但在高一些的版本中使用WebMvcConfigurer接口来替代它,且WebMvcConfigurerAdapter已过时。

# 拦截器Interceptor和过滤器Filter

过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则是基于Java的反射机制(动态代理)实现的。

相同点:都可以用来对请求进行预处理和后处理,它们都能够在请求到达Controller层之前或之后进行处理。

各自的优缺点:

拦截器的优点在于可以精确控制拦截器的执行顺序,并且可以对请求和响应进行更精细的处理;缺点在于只能在Spring MVC框架中使用,无法在其他框架中使用。

而Filter的优点在于可以在任何基于Servlet的Web应用中使用,

缺点在于执行顺序不尽如人意,无法控制Filter的执行顺序。

不同点:

过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对Controller中请求或访问static目录下的资源请求起作用。

此外,过滤器和拦截器的触发时机也不同,我们看下边这张图。

过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。

拦截器 Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。

# 日志实现

# 默认情况

SpringBoot中默认选择的搭配是:slf4j+logback,并用INFO级别输出到控制台。在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了。

springboot底层也是使用的slf4j+logback的方式进行日志记录,同时还引入了将其他日志框架转成slf4j的jar,它一定程度上帮我们解决多个日志框架转换的兼容问题(或者说它实现了自动适配所有的日志)。

image-20231119232942015

如果我们要引入其他框架,为了避免冲突,一定要把该框架的默认日志依赖给移除。

默认情况下,Spring Boot将日志输出到控制台,不会写到日志文件。如果要将日志编写输出到日志文件,则需在application.properties中设置logging.file或logging.path属性,文章下面会详细介绍。

# 开发使用

springboot项目在运行时,控制台会有日志输出,这表示它已经帮我们默认实现了,我们可以直接使用。

在日常的开发中,日志记录方法的调用,不应该直接调用日志的实现类,而是调用日志抽象层里面的方法:

给系统里面import slf4j的jar和logback的实现jar

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ATestController {

    private Logger logger = LoggerFactory.getLogger(ATestController.class);

    public void Test(){
        System.out.println("hello world");
        logger.info("hello test");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

日志的级别:

由低到高:trace< debug< info < warn < error

日志只会输出比当前设置级别更高的日志,springboot的默认级别为:info(就是说它会输出 info、warn、error)。日志级别越低,输出信息越多;越高则越少。

  • 调试模式

我们可以通过启动应用程序 --debug 标志来启用“调试”模式(开发的时候推荐开启),以下两种方式皆可:

  • 在运行命令后加入--debug标志,如:$ java -jar springTest.jar --debug
  • 在application.properties中配置debug=true,该属性置为true的时候,核心Logger(包含嵌入式容器、hibernate、spring)会输出更多内容,但是你自己应用的日志并不会输出为DEBUG级别。

# 修改输出级别跟样式

在配置文件中,logging.level设置日志级别,后面跟生效的区域

# root表示整个项目
logging.level.root=warn
# 也可以指定具体包的级别
logging.level.com.sugar=debug
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
# path 跟 file决定日志文件的位置
logging.path=spring.log
# file的优先级最高
logging.file=D:/spring.log
1
2
3
4
5
6
7
8
9
10
logging.file.name logging.file.path Example Description
(none) (none) 只在控制台进行记录。
指定文件 (none) my.log 写入指定的日志文件。 名称可以是一个确切的位置,也可以是与当前目录的相对位置。
(none) 指定目录 /var/log 将 spring.log 写到指定目录。 名称可以是一个确切的位置,也可以是与当前目录的相对位置。

若logging.file和logging.path都不指定,则日志只会在控制台输出

如果logging.file指定了文件名,则日志输出到指定的文件。若文件没有路径,只有名称,则会在当前项目中生成日志文件。

如果指定了path,则日志输出到指定目录的文件中。

若file跟path都指定了,则只会生效file。

# 在控制台输出日志的格式
logging.pattern.console=xxxxxx

# 指定文件中日志输出的格式
logging.pattern.file=xxxx
1
2
3
4
5

# 重写配置文件

springboot的日志它有一个默认配置,但它跟其他功能一样,如果我们重写了它,则会使用我们自己的配置。在类路径下放上每个日志框架的配置文件,springboot就不再使用它的默认配置了。

推荐使用带spring字样的日志文件。

日志系统 配置文件
Logback logback-spring.xml,logback-spring.groovy,logback.xml orlogback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK(Java Util Logging) logging.properties

更多文档

springboot官网-logging讲解 (opens new window)

springboot中文-logging讲解 (opens new window)

上次更新: 2025/04/23, 16:23:16
SpringBoot常用功能实现_1
多环境配置与数据绑定

← SpringBoot常用功能实现_1 多环境配置与数据绑定→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式