自动配置

学习SSM整合时,需要配置 Tomcat ,配置 Spring MVC,以及配置如何扫描包,配置字符过滤器,配置视图解析器,文件上传等。非常麻烦。而在 Spring Boot 中,存在自动配置 机制,提高开发效率。

现在,自动配置会自动配置好这些组件,容器中有什么组件,就具有什么功能

验证

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
//java10:局部变量类型的自动推断
var ioc = SpringApplication.run(MainApplication.class, args);
//1、获取容器中所有组件的名字
String[] names = ioc.getBeanDefinitionNames();
//2、挨个遍历:
// dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartReso
// springboot把以前配置的核心组件现在都给我们自动配置好了。
for (String name : names) {
System.out.println(name);
}
}

导入场景后,容器中就会自动配置好这个场景的核心组件

自动配置的触发原理

自动配置通过 @EnableAutoConfiguration 注解触发,这个注解通常包含在 @SpringBootApplication 注解中。当 Spring Boot 应用启动时,@EnableAutoConfiguration 注解会执行以下操作:

  1. 扫描类路径下的 META-INF/spring.factories 文件

    Spring Boot 在启动时会扫描类路径下所有的 META-INF/spring.factories 文件。这些文件中定义了一系列的自动配置类,它们以键值对的形式存在,其中键为 org.springframework.boot.autoconfigure.EnableAutoConfiguration,值为多个自动配置类的全限定名。例如:

    1
    2
    3
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
    org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  2. 加载配置类

    Spring Boot 会根据 spring.factories 文件中定义的自动配置类,将这些类加载到 Spring 容器中。这些自动配置类使用了 Spring 的 @Configuration 注解,本质上就是普通的 Java 配置类。

  3. 根据条件注解决定是否生效

    自动配置类中会使用大量的条件注解,如 @ConditionalOnClass@ConditionalOnMissingBean@ConditionalOnProperty 等,来决定该配置类是否生效。例如,@ConditionalOnClass 注解会检查类路径中是否存在指定的类,如果存在则该配置类生效;@ConditionalOnMissingBean 注解会检查 Spring 容器中是否已经存在指定类型的 Bean,如果不存在则该配置类生效。

@SpringBootConfiguration

查看该注解的定义,发现其上标有@Configuration,并且里面有一个唯一的属性即proxyBeanMethods。这说明被@SpringBootConfiguration修饰的类也是一个配置类。

@ComponentScan

指定扫描哪些Spring注解。

@EnableAutoConfiguration

这是SpringBoot自动配置的入口

自动配置的工作流程

image-20250525182907852

流程:

  1. 导入 starter-web:导入了 web 开发场景

    • 场景启动器导入了相关场景的所有依赖:starter-json、starter-tomcat、springmvc

    • 每个场景启动器都引入了一个 spring - boot - starter,核心场景启动器。

    • 核心场景启动器引入了 spring - boot - autoconfigure 包。

    • spring - boot - autoconfigure 里面囊括了所有场景的所有配置。

    • 只要这个包下的所有类都能生效,那么相当于 Spring Boot 官方写好的整合功能就能生效了。

    • Spring Boot 默认扫描不到 spring - boot - autoconfigure 下写好的所有配置类。(这些配置类给我们做了整合操作

  2. 主程序:@SpringBootApplication

    • @SpringBootApplication 由三个注解构成 @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
    • Spring Boot 默认只能扫描自己主程序及其所在的下面的子包,扫描不到spring-boot-autoconfigure包中官方写好的配置类
    • @EnableAutoConfiguration:Spring Boot 开启自动配置的核心
      • 是由@Import(AutoConfigurationImportSelector.class)提供功能:批量给容器中导入组件
      • Spring Boot启动会默认加载 142 个配置类
      • 这 142 个配置类来自于 spring-boot-autoconfigureMETA-INF/spring/org.springframework.boot.autoconfigurate.AutoConfiguration.imports文件指定的
      • 项目启动的时候利用 @Import 批量导入组件机制,把 autoconfigure 包下的142个 xxxAutoConfiguration类导入进来(自动配置类)
      • 虽然导入了 142 个配置类,但是并不是全部生效
    • 按需生效
      • 并不是这142个自动配置类都能生效
      • 每一个自动配置类,都有条件注解@ConditionalOnXxx,条件成立才能生效
  3. xxxAutoConfiguration类导入进来(自动配置类)

    • 给容器中使用@Bean放一堆组件
    • 每个自动配置类都可能有这个注解@EnableConfigurationProperties(xxxProperties.class),用来把配置文件中配的指定前缀的属性值封装到 xxxProperties 属性类中
    • 以 Tomcat 为例子,把服务器所有配置都是以 server 开头的,配置都封装到了属性类中
    • 给容器中放的所有组件的一些核心参数,都来自于 xxxPropertiesxxxProperties都是和配置文件绑定
    • 只需要改配置文件的值,核心组件的底层参数都能修改,这样就实现了导入了 starter,所有的配置都能生效
  4. 写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)

核心流程:

  1. 导入 starter,就会导入 autoconfigure 包。
  2. autoconfigure 包里面有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定的所有启动要加载的自动配置类。
  3. @EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来。xxxAutoConfiguration 是有条件注解进行按需加载
  4. xxxAutoConfiguration 给容器中导入一堆组件,组件都是从xxxProperties中提取属性值
  5. xxxProperties 又是和配置文件进行了绑定

效果:导入 starter、修改配置文件,就能修改底层行为

容器功能

在深入了解 Spring Boot 的自动配置功能之前,我们需要先了解 Spring Boot 的容器管理功能。在学习 Spring Framework 时,我们知道 Spring Framework 有两大核心机制:IOC(控制反转)和 AOP(面向切面编程)。

IOC 容器的主要作用是帮助我们存放对象,并管理对象的创建、装配和销毁过程。这样,原本由程序手动完成的对象管理工作就交给了 Spring Framework 来处理。在 Spring Boot 中,我们学习的核心在于如何将对象注册到 Spring 容器中,以及如何从 Spring 容器中获取对象。

Spring Boot 的默认包扫描路径

在Spring Boot 的自动配置中,我们不需要像Spring MVC 中一定要配置扫描包 。Spring Boot 有默认的扫描包结构。这使得我们在没有指定任何包扫描路径的情况下,注册到容器中的对象也能被正常获取。这是因为 Spring Boot 默认的包扫描路径下的目标对象,都会被注册进容器中。

默认的扫描路径是 Main Application Class 所在的目录以及子目录

@SpringBootApplication标注的类就是主程序类,Spring Boot 只会扫描主程序所在的包及其下面的子包

配置默认值

  • 配置文件所有配置项是和某个类的对象值是一一对应的

  • 绑定了配置文件中的每一项值的类:配置属性类

    比如 ServerProperties绑定了所有 Tomcat 配置值相关的所有配置

如果需要改变默认的扫描路径,可以通过在启动类上配置 scanBasePackages 属性来实现:

1
2
3
4
5
6
7
8
9
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages = "com.example.demo.service,com.example.demo.repository")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

该属性是一个字符串数组,可以指定多个包路径,用逗号隔开。

实际上,scanBasePackages 属性和 @ComponentScan 注解的 basePackages 属性是绑定的,因此使用 @ComponentScan 注解直接指定包扫描的路径也能达到同样的效果:

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.example.demo.service,com.example.demo.repository")
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

自动配置遵循的原则

自动配置遵守按需加载原则:也就是说,引入了哪个场景 starter启动器 就会加载该场景关联,的 jar 包,没有引入的 starter 则不会加载其关联 jar 。

SpringBoot 所有的自动配置功能都在 spring-boot-autoconfigure包里面;

在Spring Boot 中的自动配置包,一般是 XXxAutoConfiguration.java 对应 XXxProperties.java

img

组件详解

@SpringBoorConfiguration

@SpringBootConfiguration 是 Spring Boot 中的一个类级注解 ,用于指示标注的类提供应用程序配置。被它标注的类,意味着其中可以包含 @Bean 定义方法,Spring 容器会处理该配置类,进而实例化和配置 bean。

它本质上是 Spring 标准 @Configuration 注解的替代方法,功能基本相同。二者唯一区别在于,@SpringBootConfiguration 允许自动找到配置

通常开发中更常用的 @SpringBootApplication 注解,实际上自动继承了 @SpringBootConfiguration 注解。@SpringBootApplication 是一个组合注解,整合了 @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 等功能。所以一般项目中使用 @SpringBootApplication 标注主应用类,就无需再单独使用 @SpringBootConfiguration 。并且建议一个应用程序中仅使用一个 @SpringBootConfiguration@SpringBootApplication 批注。

@Configuration和@Bean

@Configuration注解表示这个类是个配置类,@Bean注解往容器中注册实例。

@Configuration把 Spring Framework 中的 xml 改成了 java config 配置类,配置类本身也是容器中的组件,组件默认都是单实例的,可以用@scope注解改,跟用<scope>标签一样。

@Bean注解替代了以前的 bean 标签,组件在容器中的名字默认就是方法名,可以修改 @Bean注解的值

1
2
3
4
5
6
7
8
9
10
11
12
13
import com.codeliu.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

@Bean
public User user() {
User user = new User("ErgouTree", 5555666);
return user;
}
}

然后在启动类中进行测试,可以发现容器中的实例都是单例的,即多次拿到的都是同一个对象。

1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
public class DockerTestApplication {

public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DockerTestApplication.class, args);
User user1 = run.getBean("user", User.class);
User user2 = run.getBean(User.class);
// true
System.out.println(user1 == user2);
}
}

@Configuration注解中的proxyBeanMethods属性即代理bean的方法,决定是否是单例模式,默认为 true 。Full模式(proxyBeanMethods = true)和 Lite(proxyBeanMethods = false)模式,Full 模式保证每个 @Bean 方法被调用多少次返回的组件都是单实例的,而 Lite 模式每个 @Bean 方法被调用多少次返回的组件都是新创建的。组件依赖必须使用 Full 模式默认,其他默认 Lite 模式

@Component@Controller@Service@Repository

不多说了,四大护法,使用在pojo、mapper、service、controller类上的注解。

@Import

第三方的任意类,都可以导入到你的配置类中作为组件,给容器中放指定类型的组件,名字默认全类名

该注解定义如下,只有一个value属性,你可以传入一个Class数组,在启动过程中,会自动帮你把类注册进容器。

1
2
3
4
5
@Configuration
@Import({User.class, DBHelper.class})
public class MyConfig {

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@SpringBootApplication
public class DockerTestApplication {

public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DockerTestApplication.class, args);
User user1 = run.getBean(User.class);
User user2 = run.getBean(User.class);
// true
System.out.println(user1 == user2);

User user = run.getBean(User.class);
// com.codeliu.entity.User@63411512
System.out.println(user);

DBHelper dbHelper = run.getBean(DBHelper.class);
// ch.qos.logback.core.db.DBHelper@35cd68d4
System.out.println(dbHelper);
}
}

可以看到,默认组件的名字是全类名。

@Conditional条件装配

意思就是满足@Conditional指定的条件,才进行组件注入。

总之就是@ConditionalOnXxx,指定的条件成立,才触发指定行为

条件注解详解

注解名称 触发条件 典型应用场景
@ConditionalOnClass 类路径存在指定类时生效 自动配置数据源
@ConditionalOnMissingBean 容器中不存在指定Bean时生效 覆盖默认配置
@ConditionalOnProperty 配置文件中存在指定属性时生效 功能开关控制
@ConditionalOnWebApplication 当前是Web应用时生效 Web相关配置
@ConditionalOnResource 存在指定资源文件时生效 特定配置文件存在时加载

属性绑定类注解@ConfigurationProperties@EnableConfigurationProperties

@ConfigurationProperties

声明组件的属性和配置文件中的哪些前缀开始进行绑定

在 Spring Boot 里,@ConfigurationProperties 能把外部配置(像application.propertiesapplication.yml 里的属性 )绑定到 Java 对象上,让配置管理更简便,配置变更更灵活动态。

这两个组件都是将容器中任意组件的属性值和配置文件的配置项进行绑定

  1. 给容器中注册组件 (@Component@Bean
  2. 使用@ConfigurationProperties 声明组件和配置文件中的哪些配置项进行绑定
  3. 可以绑定到类上,可以绑定到方法上

举例

  • 定义配置类:创建一个类,用 @ConfigurationProperties 注解标注它,并指定 prefix 属性,该属性值是配置文件中相关属性的前缀。类中定义字段来对应配置属性,同时需提供这些字段对应的 gettersetter 方法 。比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;

    @Component
    @ConfigurationProperties(prefix = "myapp")
    public class MyAppProperties {
    private String name;
    private int age;

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }
    }

    @ConfigurationProperties(prefix = "myapp") 表示会找配置文件中以 myapp 开头的属性,像 myapp.name 会绑定到 name 字段 ,myapp.age 会绑定到 age 字段。同时通过 @Component 注解将该类注册为 Spring 容器中的组件,这样容器启动时就能处理这个配置类。

  • 配置文件配置:在 application.propertiesapplication.yml 里写对应属性,例如在 application.properties 中指定其中的 name 和 age 字段

    1
    2
    myapp.name=test
    myapp.age=18
  • 使用配置:在其他组件中,可通过依赖注入使用这个配置类,获取配置属性值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    @Service
    public class MyService {
    private final MyAppProperties myAppProperties;

    @Autowired
    public MyService(MyAppProperties myAppProperties) {
    this.myAppProperties = myAppProperties;
    }

    public void doSomething() {
    System.out.println("Name: " + myAppProperties.getName() + ", Age: " + myAppProperties.getAge());
    }
    }

所以说,@ConfigurationProperties就是将配置文件(如 application.properties)中的属性值,绑定到 Java 类的字段上。在类上标注 @ConfigurationProperties(prefix = "xxx"),指定配置文件中的属性前缀。但是注意,类需提供字段的 getter/setter 方法,并且需将该类注册为 Bean。

@EnableConfigurationProperties

这个一般是用于导入第三方写好的组件,进行属性绑定,即使第三方导入了并且标注了 @Component@ConfigurationProperties注解,也不行,因为默认只扫描自己主程序所在的包。

用于显式开启对 @ConfigurationProperties 注解类的支持。告知 Spring Boot 框架,项目里有用 @ConfigurationProperties 注解的类,要自动加载配置文件属性并绑定到这些类的字段上 ,还能自动注册这些类为 Spring 容器中的 Bean。从 Spring Boot 2.2 起,若配置属性类已用 @Component 等注解注册为组件,可不显式用此注解,Spring Boot 会自动配置 。

使用方式:在主类或者配置类上使用该注解,并在 value 属性指定一个或多个 @ConfigurationProperties 注解的类。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@SpringBootApplication
// 开启 MyAppProperties 组件中的属性绑定
// 默认会把这个组件自己放到容器中
@EnableConfigurationProperties(MyAppProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

这里 @EnableConfigurationProperties(MyAppProperties.class) 让 Spring Boot 把配置文件属性绑定到 MyAppProperties 类实例上,并将其实例注册为 Spring 容器中的 Bean。

所以,@EnableConfigurationProperties的功能就是启用 @ConfigurationProperties 功能,在主类或配置类上标注 @EnableConfigurationProperties(MyConfig.class),将指定类注册为 Bean。若配置类已用 @Component 标注,则无需显式使用此注解

Spring Boot 自动配置都配置了什么

按需加载自动配置

  • 导入场景

  • 场景启动器除了会导入相关功能依赖,导入一个 spring-boot-starter ,是所有 starter 的 starter

  • 这里面还导入了一个spring-boot-autoconfigure包,都是各种场景的自动配置AutoConfig类,虽然里面有全场景的,但是是导入哪个场景就启用哪个自动配置

    image-20250525162137612

当我们导入某个场景启动器,就会触发 spring-boot-autoconfigure的自动配置生效,容器中就会具有相关场景的功能

自动配置 Tomcat

Spring Boot 默认会自动配置嵌入式的 Tomcat 服务器。当我们引入 spring-boot-starter-web 依赖时,Spring Boot 会自动检测到并为我们配置好 Tomcat 服务器。我们无需手动配置 Tomcat 的启动参数、端口号等信息,Spring Boot 会使用默认的配置启动 Tomcat 服务器。如果需要修改 Tomcat 的配置,例如修改端口号,可以在 application.propertiesapplication.yml 文件中进行配置:server.port=8081

img

自动配置了 Spring MVC

Spring Boot 会自动配置 Spring MVC 的核心组件,如 DispatcherServlet、HandlerMapping、ViewResolver 等。它会根据类路径中的依赖和配置文件中的信息,自动配置合适的视图解析器、消息转换器等。例如,当我们引入 spring-boot-starter-thymeleaf 依赖时,Spring Boot 会自动配置 Thymeleaf 视图解析器,让我们可以方便地使用 Thymeleaf 模板引擎进行视图渲染。

img

自动配置 Web 常用功能

Spring Boot 还会自动配置 Web 开发中常用的功能,如字符过滤器、静态资源映射等。

例如,它会自动配置一个字符编码过滤器,确保请求和响应的字符编码一致。默认情况下,字符编码为 UTF-8。我们可以通过配置文件修改字符编码:

1
2
3
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

我们可以通过 Debug 的方式,在 ioc 打上断点,从而查看 ioc 容器中有哪些 Bean 对象被创建了。

img
img
img
img
img
img

自定义自动配置

自定义自动配置过程

虽然 Spring Boot 的自动配置功能非常强大,但在某些情况下,我们可能需要自定义自动配置。自定义自动配置的步骤如下:

  1. 创建自动配置类:创建一个带有 @Configuration 注解的 Java 类,作为自动配置类。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Configuration
    @ConditionalOnClass(MyService.class)
    @EnableConfigurationProperties(MyServiceProperties.class)
    public class MyServiceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyServiceProperties properties) {
    return new MyService(properties.getPrefix());
    }
    }
  2. 创建 META-INF/spring.factories 文件:在 src/main/resources 目录下创建 META-INF/spring.factories 文件,并在文件中指定自动配置类的全限定名:

    1
    2
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.demo.MyAutoConfiguration
  3. 定义配置:为了让自动配置更加灵活,可以在自动配置类中使用条件注解,根据不同的条件决定是否生效。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    @Configuration
    @ConditionalOnClass(MyService.class)
    public class MyAutoConfiguration {
    @Bean
    public MyService myService() {
    return new MyService();
    }
    }

调试自动配置

我们可以通过 Debug 的方式,在 IOC 容器初始化的过程中打上断点,从而查看 IOC 容器中有哪些 Bean 对象被创建了。此外,Spring Boot 还提供了 --debug 启动参数,当我们在启动应用时添加该参数,Spring Boot 会输出详细的自动配置报告,帮助我们了解自动配置的过程和结果。例如,在命令行中启动应用时添加 --debug 参数:

1
java -jar myapp.jar --debug

查看生效配置

1
2
# 启用自动配置报告
debug=true

Spring Framework原生配置文件引入

@ImportResource注解可以导入 Spring 的配置文件,让配置文件里的内容生效。因为有些项目 bean 定义在 xml 文件里,但你必须知道 xml 文件的路径,这样在项目启动的时候 Spring 才会加载配置文件。那对于 Spring Boot 项目来说,所有的 bean 都是通过 java 配置实现,xml 没有用武之地了吗?

@Configuration搭配@ImportResource可以实现xml配置的装载。

1
2
3
4
5
6
7
8
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ImportResource("classpath:beans.xml")
public class MyConfig {

}

Spring Boot 中的 application.properties

自定义 application.properties 中的配置

SpringBoot 项目最重要也是最核心的配置文件就是 application.properties,所有的框架配置都可以在这个配置文件中说明

在Spring Boot中各种配置都有默认,当然可以自定义

特别注意:该文件名必须是 application.properties,后缀也不可以修改。强烈建议将其放到 类的根路径下(也就是resources 目录下 )

其次是,注意:在.properties 后缀的配置文件,当中编写,不要有空格,尽量不要有空格。

在 Spring Boot 里,我们可以借助 .properties 文件进行自定义配置,并且利用 @Value("${}") 注解来获取这些配置的属性值。这样做能让我们更灵活地管理应用的配置信息,而不需要将这些信息硬编码在代码里。

在需要使用这些配置信息的 Java 类里,我们可以通过 @Value 注解来注入配置属性值。下面是一个示例

1
2
3
4
5
6
7
# 自定义数据库连接信息
custom.db.url=jdbc:mysql://localhost:3306/mydb
custom.db.username=root
custom.db.password=123456

# 自定义应用名称
custom.app.name=MySpringBootApp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class CustomConfig {

// 使用 @Value 注解获取 custom.db.url 的值
@Value("${custom.db.url}")
private String dbUrl;

// 使用 @Value 注解获取 custom.db.username 的值
@Value("${custom.db.username}")
private String dbUsername;

// 使用 @Value 注解获取 custom.db.password 的值
@Value("${custom.db.password}")
private String dbPassword;

// 使用 @Value 注解获取 custom.app.name 的值
@Value("${custom.app.name}")
private String appName;

// Getter 方法,用于获取数据库连接 URL
public String getDbUrl() {
return dbUrl;
}

// Getter 方法,用于获取数据库用户名
public String getDbUsername() {
return dbUsername;
}

// Getter 方法,用于获取数据库密码
public String getDbPassword() {
return dbPassword;
}

// Getter 方法,用于获取应用名称
public String getAppName() {
return appName;
}
}

我们可以在服务类或者控制器里注入 CustomConfig 类的实例,然后使用其中的配置信息。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigController {

// 注入 CustomConfig 类的实例
@Autowired
private CustomConfig customConfig;

// 处理 GET 请求,返回应用名称
@GetMapping("/app-name")
public String getAppName() {
return customConfig.getAppName();
}

// 处理 GET 请求,返回数据库连接信息
@GetMapping("/db-info")
public String getDbInfo() {
return "DB URL: " + customConfig.getDbUrl() +
", Username: " + customConfig.getDbUsername() +
", Password: " + customConfig.getDbPassword();
}
}
  • 默认值设置:如果 .properties 文件中没有定义某个属性,而我们又使用了 @Value 注解去获取该属性值,应用启动时会抛出异常。为了避免这种情况,我们可以给 @Value 注解设置默认值,示例如下:

    1
    2
    @Value("${custom.db.port:3306}")
    private int dbPort;

    上述代码中,如果 custom.db.port 属性没有在 .properties 文件中定义,dbPort 会被赋予默认值 3306

配置文件的优先级

Spring Boot 支持多种配置文件,如 application.propertiesapplication.yml 以及不同环境的配置文件(如 application-dev.propertiesapplication-prod.properties)。这些配置文件有不同的优先级,需要注意它们之间的覆盖关系。

Spring Boot 中在哪里配置读取 application.properties 配置文件

打开 ConfigFileApplicationListener.java , 看一下源码

img
1
2
3
4
5
// 指明: application.properties 可以存放的位置在哪里,Spring Boot 可以成功读取到 
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";

// 指明: 配置类,要是为:application,
private static final String DEFAULT_NAMES = "application";