SpringBoot学习笔记(上)——自动装配原理、自定义 springboot-starter、配置文件编写
目录
一、创建SpringBoot的方式
二、pom.xml配置文件
三、主程序类,入口类
1、@SpringBootApplication
2、SpringBoot自动配置的核心步骤(代码流程)
3、总结,面试回答
四、自定义 springboot-starter
1、实现流程
2、遇到的问题
五、热部署
六、application配置文件
1、YAML基本语法
2、配置文件注入
3、@Value获取值和@ConfigurationProperties获取值比较
4、@PropertySource 和 @ImportResource
5、多文件配置
一、创建SpringBoot的方式
1、 idea直接从Spring Initializr官网下载即可(正常创建,java版本不可使用8)
2、Idea从阿里云的官网(https://start.aliyun.com)下载打开(java版本可使用8)
3、自己从spring官网下载再用idea打开
4、从阿里云官网下载再用idea打开
5、Maven项目改造成springboot项目
需要在maven项目中加入如下依赖:
1、添加对父工程的依赖:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.3</version>
</parent>
2、添加spring-web-starter-web依赖,web启动器,它为我们提供了servlet容器以及SpringMVC的依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
3、在com.mszlu.demo1中创建启动类SpringDemo1Application:
并在类上加入注解@SpringBootApplication,声明该类是SpringBoot的启动类。
如下:
@SpringBootApplication
public class SpringDemo1Application {public static void main(String[] args) {SpringApplication.run(SpringDemo1Application.class, args);}}
4、在resources目录下新建文件application.properties(优先级更高)或application.yml 文件
在两个配置文件都存在且相同的配置情况下,例如server.port,那么会优先采用.properties文件,如果.properties中的配置文件不存在,会再去.yml文件中去寻找。
否则有哪个配置就采取哪个配置
这样maven项目改为springboot项目便完成了
二、pom.xml配置文件
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.3</version><relativePath/> <!-- lookup parent from repository -->
</parent>
通过<parent>指定spring-boot-starter-parent:3.5.3.RELEASE作为父项目,这是 Spring Boot 提供的 “Starter 父项目”,它的作用是:
- 1、统一管理SpringBoot的相关依赖版本(不需要在子项目配置版本)
- 2、提供默认的Maven插件配置
这个spring-boot-starter-parent的父项目是
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>3.5.3</version>
</parent>
它是真正管理SpringBoot应用里面所有依赖版本,Spring Boot的版本仲裁中心;
以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖则需要声明版本号)
启动器
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web:
spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件
spring boot将所有功能场景都抽取出来,做成一个个starters(启动器),只需在项目里面引入这些starter
相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
三、主程序类,入口类
1、@SpringBootApplication
@SpringBootApplication 来标注一个主程序类和主配置类,说明这是一个springboot应用,通过运行该类的main方法来启动springboot应用
点开@SpringBootApplication注解,可以看到如下注解:
该注解由四个元注解和三个其他注解组成
主要的三个注解:
1、@SpringBootConfiguration:标识该类是SpringBoot配置类,和@Configuration作用一致,会作为bean被注册到spring容器中
2、@ComponentScan:扫包的注解,扫描当前包及其子包下的所有Spring组件
3、@EnableAutoConfiguration:启用SpringBoot自动配置机制
其中@EnableAutoConfiguration是自动配置的核心,它引导自动配置
Spring Boot 会扫描 classpath 中所有 META-INF/spring.factories
文件,加载 EnableAutoConfiguration
对应的配置类(如 DataSourceAutoConfiguration
、WebMvcAutoConfiguration
等),自动创建 Bean 并注入容器,省去大量手动配置。
@EnableAutoConfiguration
主要包含两个注解:1、AutoConfigurationPackage 2、AutoConfigurationImportSelector
1、 AutoConfigurationPackage:自动配置包
主要作用是:将主应用类(即添加 @SpringBootApplication
的类)所在的包及其子包里面的所有组件扫描到Spring容器;
注解内部:Import(AutoConfigurationPackages.Registrar.class):
Registrar
类:这是一个 ImportBeanDefinitionRegistrar,它会在 Spring 容器启动时动态注册一个 BasePackages
Bean。
2、AutoConfigurationImportSelector
该注解内部引用了AutoConfigurationImportSelector,这是自动配置的核心处理器
AutoConfigurationImportSelector类会从配置文件(通常是spring.factories)中读取所有的自动配置类,并将它们导入到应用上下文中。
spring.factories文件:
自动配置类是通过 spring-boot-autoconfigure
模块的 META-INF/spring.factories
文件来配置的。这个文件中列出了所有可以被自动加载的配置类:
这些配置类会在SpringBoot启动时,根据当前的环境选择性加载
条件装配
SpringBoot并不是盲目的加载所有的自动配置类。每个自动配置类通常会使用@Conditional系列注解来进行有条件的加载,最常见的条件注解有:
- @ConditionalOnClass:当类路径存在某个类时才生效
- @ConditionalMissingBean:当Spring上下文中不存在某个Bean时生效
- @ConditionalOnProperty:当某个配置属性满足特定条件时才生效
- @ConditionalOnBean:当Spring上下文中存在某个Bean时才生效
例如DataSourceConfiguration只有在项目存在数据源相关的依赖(javax.sql.DataSource
类)才会被加载
自动配置类示例:
@Configuration
@ConditionalOnClass(JdbcTemplate.class) // 仅当类路径存在 JdbcTemplate 时生效
public class JdbcTemplateAutoConfiguration {@Bean@ConditionalOnMissingBean // 仅当用户未自定义 DataSource 时创建默认 Beanpublic DataSource dataSource() {// 创建默认数据源(如 HikariCP)}
}
@ConditionalOnClass(DataSource.class)
:只有当类路径下存在DataSource
类时,才进行数据源的自动配置。@ConditionalOnMissingBean
:如果 Spring 上下文中没有其他DataSource
Bean,则自动配置一个。
2、SpringBoot自动配置的核心步骤(代码流程)
@SpringBootApplication注解里面的@EnableAutoConfiguration,通过@Import导入AutoConfigurationImportSelector类,该类实现了selectImports接口,用于实现自动配置的选择和导入。具体来说,它通过分析项目的类路径和条件来决定应该导入哪些自动配置类。
public class AutoConfigurationImportSelector implements
DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {//获取所有符合条件的类全限定名,这些类需要被加载到Ioc容器中public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}// 只提取了主要功能protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {//1.检查自动配置是否启用if (!this.isEnabled(annotationMetadata)) {return EMPTY_ENTRY;} else {// 2.从META-INF/spring.factories中加载所有候选自动配置类//(这些类是Spring Boot预定义的,如DataSourceAutoConfiguration、WebMvcAutoConfiguration等)List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);// 3.去除重复的配置类configurations = this.removeDuplicates(configurations);//....// 4.过滤配置类,通过条件注解(@ConditionalOnClass等)判断是否符合加载条件 configurations = this.getConfigurationClassFilter().filter(configurations);//5.返回处理结果return new AutoConfigurationEntry(configurations, exclusions);}}protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {//获取自动配置类的候选列表,从META-INF/spring.factories文件中读取List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");return configurations;}List<String> filter(List<String> configurations) {// 1. 将配置类列表转为数组以便后续操作String[] candidates = StringUtils.toStringArray(configs);// 2. 遍历所有过滤器,标记不符合条件的配置类(置为null)this.filters.forEach(f -> { boolean[] matches = f.match(candidates, metadata); for (int i = 0; i < matches.length; i++) {if (!matches[i]) candidates[i] = null; }});// 3. 过滤掉被标记的配置类,返回有效列表return Arrays.stream(candidates).filter(Objects::nonNull).collect(Collectors.toList());}
}
梳理下,这是AutoConfigurationImportSelector的主要工作
1.扫描类路径:在应用程序启动时,AutoConfigurationImportSelector会扫描类路径上的META-INF/spring.factories文件,这个文件包含了spring配置和拓展的定,在这里它会查找所有实现了AutoConfiguration接口的类,具体的实现为getCandidateConfigurations方法中.
2.条件判断:对于每一个发现的自动配置类,AutoConfigurationImportSelector会使用条件判断机制(通常是通过@conditionalOnXxx注解)来确定是否满足导入条件。这些条件可以是配置属性、类是否存在、Bean是否存在等等。
3.根据条件导入自动配置类:满足条件的自动配置类将被导入到应用程序的上下文中。这意味着它们会被实例化并应用于应用程序的配置。
3、总结,面试回答
@SpringBootApplication启动类注解由四个元注解还有:@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解组成,由这三个注解共同完成自动装配
@SpringBootConfiguration:声明该类为配置类,和spring的@Configuration类一样
@ComponentScan 注解实现启动时扫描启动类所在的包及其子包下所有标记为bean的类,将其注册到IOC容器中
@EnableAutoConfiguration:通过@Import注解导入AutoConfigurationImportSelector类,然后通过该类中的selectImports方法去读取外部引用jar包中的META-INF/spring.factories文件配置的类全名,并根据条件装配过滤掉不符合要求组件的类全名,将剩余读取到的组件类全名集合返给Ioc容器并注册为bean
相关元注解含义:
1. @Target(ElementType.TYPE)
元注解,限定 @SpringBootApplication
只能用在类、接口、枚举(TYPE
代表 “类型级别”)上,不能用在方法、字段等其他位置。
2. @Retention(RetentionPolicy.RUNTIME)
元注解,指定注解的保留策略:
RUNTIME
表示注解会保留到 运行时,可通过反射(如 Class.getAnnotations()
)在程序运行阶段获取注解信息,Spring 自动配置、组件扫描等核心逻辑依赖此特性。
3. @Documented
元注解,标记该注解会被 Java 文档工具(javadoc) 提取到 API 文档中,生成文档时会包含此注解说明,方便开发者查阅。
4. @Inherited
元注解,让注解具备继承性:如果父类使用了带 @Inherited
的注解(如 @SpringBootApplication
所在类),子类会自动继承该注解(无需显式声明),不过实际场景中 Spring Boot 启动类一般不这么用,但语法上支持。
四、自定义 springboot-starter
实现一个功能,提供helloService,可通过配置文件配置问候语前缀,调用其方法时 将参数和前缀拼接。
1、实现流程
例如在配置文件中配置前缀:"hello",参数为:"HYX",则输出结果为 "hello HYX"
1、创建项目hyx-spring-boot-starter
Starter本质上一个普通的maven项目,通过特定的配置让springboot自动识别并加载
2.pom.xml依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- 必须:Starter 基础依赖(自动配置核心) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><!-- 可选:配置属性元数据(IDE 提示用) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!-- 重要!为可执行 JAR 增加后缀,例如 xxx-exec.jar --><classifier>exec</classifier></configuration></plugin></plugins>
</build>
3.HelloService.java
package com.mszlu.hyxspringbootstarter;public class HelloService {// 问候语前缀(可通过配置文件自定义)private String prefix;public HelloService(String prefix) {this.prefix = prefix;}// 核心方法:生成问候语并拼接前缀public String sayHello(String name) {return prefix + ", " + name + "!";}
}
4.配置属性类HelloProperties
用于绑定配置文件中的属性(如 hello.prefix=Hello
):
@ConfigurationProperties(prefix = "hello")
public class HelloProperties {private String prefix = "Hello";// getter 和 setter(必须有,用于属性绑定)public String getPrefix() {return prefix;}public void setPrefix(String prefix) {this.prefix = prefix;}
}
5.自动配置类 HelloAutoConfiguration
@Configuration
@EnableConfigurationProperties(HelloProperties.class)
public class HelloAutoConfiguration {// 注入配置属性(从 HelloProperties 中获取 prefix)private final HelloProperties helloProperties;public HelloAutoConfiguration(HelloProperties helloProperties) {this.helloProperties = helloProperties;}// 注册 HelloService 为 Spring Bean// @ConditionalOnMissingBean:如果用户自己定义了 HelloService Bean,就用用户的,否则用这里的@Bean@ConditionalOnMissingBeanpublic HelloService helloService() {// 用配置文件中的 prefix 初始化 HelloServicereturn new HelloService(helloProperties.getPrefix());}
}
6.声明自动配置类
Spring Boot 3.0+ 不再使用 spring.factories
,而是通过 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件声明自动配置类
- 在
src/main/resources
下创建目录META-INF/spring
; - 新建文件
org.springframework.boot.autoconfigure.AutoConfiguration.imports
,内容为自动配置类的全路径:
com.mszlu.hyxspringbootstarter.HelloAutoConfiguration
7.打包Starter
执行maven install,将Starter安装到本地仓库
创建测试项目(使用自定义Starter)
1、新建一个普通的springboot项目,在依赖中引用上面的Starter并测试
<dependency><groupId>com.mszlu</groupId><artifactId>hyx-spring-boot-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
2、在application.properties文件中配置 前缀语
hello.prefix="hyxAndlyl",不配置则使用默认值hello
3、测试控制器(TestController)
注入HelloService并测试功能
@RestController
public class TestComtroller {@AutowiredHelloService helloService;@GetMapping("hello/{name}")public String hello(@PathVariable String name) {return helloService.sayHello(name);}
}
4、测试结果,当输入127.0.0.1/hello/world时,会输出:
2、遇到的问题
1、打包好Starter以后,在测试项目中导入依赖后,无法正常导入Starter中的类
原因:
1、java 打包jar格式分为普通jar包 和 可执行jar包
普通项目(无springboot)默认打包的xxx.jar是 普通jar包(因为类文件直接放在 JAR 根目录,不包含第三方依赖,仅保留项目自身的编译产物。)
SpringBoot项目:默认打包的xxx.jar 是可执行jar包。
一、核心概念:两种 JAR 包的本质区别
维度 | 普通 JAR 包(Plain JAR) | 可执行 JAR 包(Executable JAR) |
---|---|---|
结构 | 类文件直接放在 JAR 根目录,仅包含项目自身编译产物(.class、资源文件等),不包含第三方依赖。 | 内部结构特殊:项目类放在BOOT-INF/classes ,第三方依赖放在BOOT-INF/lib ,包含 Spring Boot 启动器(如JarLauncher )和特殊的MANIFEST.MF (指定启动类)。 |
可执行性 | 不可通过java -jar 运行(缺少启动类和类加载逻辑)。 | 可直接通过java -jar xxx.jar 运行(内置启动逻辑)。 |
依赖性 | 可被其他项目依赖(类加载器能直接识别根目录的类)。 | 不可被其他项目依赖(类在BOOT-INF 目录,普通类加载器无法识别,会导致 “类找不到”)。 |
普通 Java 项目(非 Spring Boot)的打包流程
- 打包命令:默认使用 Maven 的
package
目标(mvn package
)。 - 产物:仅生成普通 JAR 包(如
demo-1.0.0.jar
)。 - 用途:作为库被其他项目依赖(因为结构简单,类可被直接识别)。
- 特点:不包含第三方依赖(依赖需由引用它的项目自行管理),也不能独立运行。
Spring Boot 项目的默认打包流程(无特殊配置)
Spring Boot 通过spring-boot-maven-plugin
插件实现特殊打包,核心是repackage
目标(默认绑定在package
生命周期后,自动执行),流程分两步:
-
第一步:执行
mvn package
生成普通 JAR 包(包含项目自身类和资源,可被依赖,但不可执行)。 -
第二步:自动执行
repackage
- 对第一步的普通 JAR 包进行二次处理,生成可执行 JAR 包(如
demo-1.0.0.jar
,结构符合 Spring Boot 规范,可直接运行)。 - 将第一步生成的原始普通 JAR 包重命名为
xxx.original
(如demo-1.0.0.jar.original
,作为 “可被依赖” 的备份)。
- 对第一步的普通 JAR 包进行二次处理,生成可执行 JAR 包(如
- 最终产物:两个文件
demo-1.0.0.jar
:可执行 JAR(用于运行)。demo-1.0.0.jar.original
:普通 JAR(可被依赖,但文件名不直观)。
让 Spring Boot 同时生成 “清晰的普通 JAR” 和 “可执行 JAR”
如果需要 Spring Boot 项目既可以被其他项目依赖(用普通 JAR),又可以独立运行(用可执行 JAR),且文件名直观,需配置classifier
:
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><!-- 为可执行JAR添加后缀(如exec) --><classifier>exec</classifier></configuration></plugin></plugins>
</build>
打包流程变化:
mvn package
生成普通 JAR(保留原名,如demo-1.0.0.jar
,可被依赖,不可被执行)repackage:
- 对第一步的普通 JAR 包不再进行二次处理,保留原始.jar包(如
demo-1.0.0.jar
,结构符合 Spring Boot 规范,不可运行,可被其他项目依赖)。 - 将可执行 JAR 包重命名为“原名-classifier后缀.jar"(如
demo-1.0.0-exec.jar
,作为 “可被依赖” 的备份)。
- 对第一步的普通 JAR 包不再进行二次处理,保留原始.jar包(如
最终产物:两个分工明确的文件:
demo-1.0.0.jar
:普通 JAR(供其他项目依赖)。demo-1.0.0-exec.jar
:可执行 JAR(供自身运行)。
三、为什么可执行 JAR 不能作为依赖被引用?
关键原因是 类加载器无法识别可执行 JAR 的嵌套结构:
- 类路径查找机制限制
当一个项目依赖另一个 JAR 时,Java 类加载器会默认在 JAR 的根目录下查找类文件(如com/example/UserService.class
)。但可执行 JAR 的类被放在BOOT-INF/classes
目录下,类加载器无法感知这个路径,会报ClassNotFoundException
(找不到类)。例如:如果项目 A 依赖可执行 JAR,当 A 尝试调用com.example.UserService
时,类加载器会去 JAR 根目录找com/example/UserService.class
,但实际路径是BOOT-INF/classes/com/example/UserService.class
,自然找不到。 - 依赖冲突风险
可执行 JAR 包含了所有第三方依赖(如spring-boot-starter-web
及其传递依赖),如果将它作为依赖引入其他项目,会导致重复依赖(例如项目 B 自身也依赖了spring-boot-starter-web
,但版本可能与可执行 JAR 中的不同),引发类冲突或版本兼容问题。 - 设计目标不同
- 普通 JAR 的设计目标是作为模块被复用,因此只包含自身代码,依赖由外部管理。
- 可执行 JAR 的设计目标是独立运行,因此需要打包所有依赖,并通过专属类加载器解析嵌套结构。
五、热部署
Java 热部署(Hot Deployment)是指在应用程序不停止运行的情况下,动态更新代码、配置或资源文件的技术。它主要用于开发阶段,能显著减少因代码修改而频繁重启应用的时间成本,提高开发效率。
spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用。
引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional>
</dependency>
修改java代码或者配置文件模板后可以通过ctrl+f9来实施热部署。
六、application配置文件
SpringBoot使用一个全局的配置文件,配置文件名是固定的
两个文件:application.properties/application.yml
作用:修改springboot自动配置的默认值,springboot在底层都给我们配置好了。
其中application.properties优先级更高,在相同配置下,优先采用.properties文件
1、YAML基本语法
a.key:(空格)value:表示一对键值对(空格必须有)
b.以空格的缩进来控制层级关系,只要是左对齐的一列数据,都是同一个层级的,
其中属性和值都是大小写敏感。
c.值的写法:直接写值(数字、字符串、布尔等),字符串不用加引号
如果加引号时,单引号和双引号有区别:
双引号:会解析特殊字符,比如\n
会变成换行
单引号:不解析特殊字符,纯原生字符串
但以上区别只在yml配置文件中生效,在properties配置文件中无论单双引号都会被解析为特殊字符
此时在yml中给lastname='hyx\n hyx'
yml中,lastname单引号输出:
lastname双引号输出:
当属性为Map、引用对象时:
行内写法:
Map:
maps: {k1: 15,k2: 14}
对象:
dog: {name: dog1,age: 3}
缩进写法:
Map:
maps:k1: 15k2: 14
对象:
dog:name: dog1age: 3
当属性为数组(List,Set)时
用 - 表示一个元素,缩进写法:
lists:- list1- list2
行内写法:
lists: ["11","22","333"]
2、配置文件注入
配置文件
person:last_name: "hyx\n hyx"age: 21birth: 2025/06/09boss: falsemaps:k1: 15k2: 14lists: [11,22,333]dog:name: dog1age: 3# dog: {name: dog1,age: 3}email: "22222"
JavaBean
//将配置文件中配置的每一个属性的值,映射到这个组件上
//@ConfigurationProperties:告诉SpringBoot将本类和配置文件中的相关配置进行绑定
// prefix=“person” : 对配置文件中哪个下面(比如这个是person)下的所有属性进行一一映射//只有这个组件是容器中的组件,才可以使用容器提供的ConfigurationProperties功能
//@ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {private String email;private String lastname;private int age;private boolean boss;private Date birth;private Map<String, Integer> maps;private List<String> lists;Dog dog;//Getter And Setter
}
可以导入文件配置处理器,这样编写配置时就有提示了
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
3、@Value获取值和@ConfigurationProperties获取值比较
“松散绑定”(Relaxed Binding)是@ConfigurationProperties
的特性,指配置文件中的 key 和 JavaBean 的属性名不需要严格一致,支持多种格式匹配。
@Value
不支持松散绑定,必须严格匹配配置文件中的 key(比如@Value("${user.user-name}")
不能写成@Value("${user.userName}")
)。
配置文件yml或properties, 两种注解方式都能获取到其中的值;
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
4、@PropertySource 和 @ImportResource
@PropertySource 加载指定的配置文件,将配置文件中的每一个属性的值,都映射到这个组件中
@PropertySource(value={"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String email;private String lastname;private int age;private boolean boss;private Date birth;private Map<String, Integer> maps;private List<String> lists;Dog dog;
}
. 配置文件加载
@PropertySource("classpath:person.properties")
:
-
- 明确指定从类路径下的
person.properties
加载属性。 - 该文件中的属性会被加入 Spring 的
Environment
,优先级高于主配置文件(如application.properties
)。
- 明确指定从类路径下的
. 属性绑定
@Component
+ @ConfigurationProperties(prefix = "person")
:
@Component
:将Person
类注册为 SpringBean,使其能被组件扫描发现。@ConfigurationProperties:
将person.properties中以person.为前缀的属性映射到Person类的对应字段
如果不加@ConfigurationProperties,得需要自己手动加@Value 来进行获取对应属性值。其对于复杂类型,需要进一步处理
person.properties文件内容:
person.lastname=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=1
person.maps.k2=2
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15
@ImportResource
导入Spring配置文件,让配置文件里面内容生效
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;
想让spring的配置文件生效,加载进来,需要将@ImportResource标注在一个配置类上
在Springboot中,肯定是将其放在启动类上,因为springboot启动类中有一个@SpringBootConfiguration将其声明为配置类,是 Spring 容器扫描和初始化的起点。
当启动类被加载时,Spring 会解析其上的所有注解,包括 @ImportResource
,并根据注解指定的路径加载 XML 配置文件。
1、编写bean.xml文件:
配置一个第三方jar包,并将其声明为bean,现在需要将该配置文件生效
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="abc"/></bean>
</beans>
2、在启动类上加入注解:@ImportResource("classpath:bean.xml")
3、此时该配置文件便成功生效了,进入了Spring容器,下面将在测试类中测试下:
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class PersonTest {@Autowiredprivate DataSource dataSource;@Testpublic void testApplicationContext() {Object dataSource1 = applicationContext.getBean("dataSource");System.out.println(dataSource1);}
}
此时便可以成功输出内容了,输入dataSource已经被成功装入了。
5、多文件配置
1、多Profile文件
我们在编写主配置文件时,文件名可以是application-{profile}.properties/yaml
默认使用application.properties文件
server.port=8080
spring.profiles.active=build
2、yaml多文件
yaml是与properties不同的是可以在同一个文件中配置多个环境,不同的环境间使用"---"进行分隔,在最顶层
注意:springboot3.0以后的版本必须采用如上配置,否会报错,3.0以下的版本可以采用如下配置方式:
spring:profiles: dev # 旧的配置方式
3.激活指定profile
1、在主配置中使用spring.profiles.active: <指定profile>
2、如果是命令行执行,可以在运行命令后面加上 --spring.profiles.active=dev
4.配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
1、–file: ./config/
2、–file: ./
3、–classpath:/config/
4、–classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;