Spring Boot 如何覆盖自动配置
创始人
2025-05-02 22:00:55
0

[[415748]]

本文转载自微信公众号「七哥聊编程」,作者七哥。转载本文请联系七哥聊编程公众号。

本文提供完整代码示例,详见 https://gitee.com/isevenluo/spring-road/ 的 spring-road03 目录。

1. 缘起

众所周知,Spring Boot 提供一个牛逼哄哄的特性,帮助我们少写了很多模板化的配置代码,这个特性就是:自动配置。

比如 Spring Data JPA,Spring Security 只要引入相关的依赖包,就会帮助我们自动配置好数据源 Bean 和 安全设置相关的 Bean,不用我们自己写配置就实现了相应的功能。

但是具体应用中,我们的实际情况往往都是比较复杂的,仅仅通过 Spring 自动配置是不能满足我们的需求的。就拿安全配置来说,在 Classpath 添加 Spring Security 后,默认为我们应用程序提供的安全设施是比较基础且粗暴的。我们在 Web 中访问应用程序,就会看到如下类似的身份验证对话框:

此处的用户名是 user,密码就比较蛋疼了,在应用每次启动时随机生成写入到日志里面了:

Spring Security 自动配置生成的密码

虽然我们的应用已经算是一个安全的 Web 应用程序了,但是也有如下显著缺点:

  1. 页面太简陋,这个对话框很不友好呀;
  2. 应用程序只有一个登录用户;
  3. 用户密码还要在应用启动日志中查看(默认用户名是user,密码是在应用启动时随机生成写入日志的);

那如何调整自动配置让 Spring 按照我们的需要进行配置呢?别着急,我们接着往下看。

一般我们覆盖 Spring Boot 默认自动配置的方式有两种:自定义配置Bean、修改外置属性进行配置。

2. 自定义配置Bean覆盖自动配置

覆盖自动配置的第一种方法呀,就是我们当自动配置不存在,自己手动配置对应的 Spring Bean。配置方式可以选择 XML,也可以用 Java 形式的配置。

今天七哥就选择目前更加流行的 Java 形式的配置,来演示一下如何覆盖我们上面所描述的自动配置的 Spring Security。

我们所要做的很简单,那就是写一个扩展类。

  1. @Configuration 
  2. @EnableWebSecurity 
  3. public class SecurityConfig extends WebSecurityConfigurerAdapter { 
  4.  
  5.     private Logger logger = LoggerFactory.getLogger(SecurityConfig.class); 
  6.  
  7.     @Resource 
  8.     private ViewerRepository viewerRepository; 
  9.  
  10.     @Override 
  11.     protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
  12.         auth.userDetailsService(username -> { 
  13.             viewerRepository.save(new Viewer(username, "{noop}123","ADMIN")); 
  14.             logger.info(viewerRepository.findViewerByUsername(username).toString()); 
  15.             return viewerRepository.findViewerByUsername(username); 
  16.         }); 
  17.     } 
  18.  

上面的代码中的 SecurityConfig 是个非常基础的 Spring Security 配置,有了它我们的 Spring Boot 应用程序就跳过了安全自动配置,不再使用默认的用户名和密码,而是使用我们定义的用户和密码来鉴权。

当然上面的代码展示的不全,但是剩下的类都不是重点,我还定义了一个 Viewer 类,实现了 UserDetails 类(Spring Security 中的用户接口),还有一个 Spring Data JPA 仓库接口,用来保存用户信息。详细的代码,都已经上传到开源仓库了,有需要的小伙伴自取哦 ~

??? 这里我们再次强调一遍:想要覆盖 Spring Boot 的自动配置,我们只需要写一个显式的配置,这样 Spring Boot 就会发现我们的配置,然后就会降低自动配置的优先级,以我们自己写的为准。

3. 通过配置属性来调整自动配置

这种配置属性文件的方式,相比于上面这种自定义 Bean 配置要简单很多。比如假设我们仅仅要 调整一个数据库的 URL、Spring Security 的默认用户名、应用日志的级别,如果都像上面那样覆盖自动配置,自己完整的声明一个 Bean,这就有点傻了!毕竟配置一个属性要比完整写一个 Bean 的配置要简单的多。

那如何配置属性呢?

Spring Boot 应用程序支持的配置源有很多,比如说环境变量、命令行参数,当然最常见的还是属性文件里配置。

接下来给大家演示几个很常见的例子。

  • Spring Boot 应用程序启动时,命令行会打印一个 Banner,如果你想禁用这个 Banner,可以将 spring.main.banner-mode 属性设置为 off 即可;

添加属性前:

在属性文件 application.properties 中添加属性 spring.main.banner-mode=off 后:

结果已经打开在控制台了,启动时的 Banner 已经不见了。

  • 调整配置应用程序的日志;

Spring Boot 默认使用 Logback来记录日志,并且用 INFO 级别输出到控制台。Logback一般情况下能很好的满足我们的需要,但是这里为了演示,假如我们要使用 Log4j2 替换默认的 Logback实现,需要怎么配置呢?

以 Gradle 为例,我们只需要修改起步依赖,在构建说明文件中引入对应的日志实现然后排除掉 Logback。

  1. configurations { 
  2.     all*.exclude group:'org.springframework.boot' , module:'spring-boot-starter-logging' 

上面我们排除掉默认的日志依赖后,就可以引入我们需要的 Log4j2 日志依赖。

  1. dependencies { 
  2.     implementation 'org.springframework.boot:spring-boot-starter-log4j2' 

接下来如果还需要做一个常规的操作:修改日志级别和指定日志输出的文件。

当然我们以往的做法就是自己添加一个 log4j2.xml 文件,用来配置日志相关的信息,虽然这样可以让我们完全掌握应用程序的日志配置,但是仅仅修改日志级别和日志输出的文件则可以完全不用创建 log4j2.xml 文件,使用属性配置就可以实现。

我们在 Spring Boot 应用程序的 application.properties 文件中加入 logging 开头的属性就可以满足我们期望。

  1. // 指定日志级别为debug 
  2. logging.level.root=debug 
  3. // 指定日志文件路径 
  4. logging.file.name=/Users/sevenluo/IdeaProjects/spring-road/spring-labs/spring-road03/logs/spring-road03.log 

至此,说明了通过上面的属性配置也实现了我们对于 Spring Boot 应用程序自动配置的微调。

4. 总结

今天我们介绍了两种覆盖 Spring Boot 自动配置的方法。

第一种就是自定义配置 Bean,实现原理是通过 Spring 的条件化配置,这块有一个非常重要的注解就是 @ConditionalOnMissingBean ,意思是如果我们的 classpath 中没有发现相应类型的 Bean,Spring Boot 才会帮我们自动配置一个。Spring Boot 的设计是优先加载我们应用里面配置的类,然后在考虑自动配置类。

第二种就是通过配置属性来调整 Spring Boot 自动配置,实现原理就是设定不同属性源里配置的属性优先级不同,而我们应用程序属性文件中添加的属性配置优先级高于默认属性,所以实现了调整自动配置的目的。

 

今天就先聊到这里,更多关于 Spring 相关的内容,也在持续更新中,敬请关注!

 

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...
《非诚勿扰》红人闫凤娇被曝厕所... 【51CTO.com 综合消息360安全专家提醒说,“闫凤娇”、“非诚勿扰”已经被黑客盯上成为了“木...
2012年第四季度互联网状况报... [[71653]]  北京时间4月25日消息,据国外媒体报道,全球知名的云平台公司Akamai Te...