1.关于 SpringBootSpringBootSpringBoot 的配置文件
1.0 配置文件的类型
SpringBootSpringBootSpringBoot 支持以下两类配置文件。
-
后缀为 .properties.properties.properties 的文件
-
后缀为 .yml.yml.yml 的文件
1.1 配置文件的位置
在创建一个 SpringBootSpringBootSpringBoot 工程时,默认在 resourcesresourcesresources 目录下有一个 application.propertiesapplication.propertiesapplication.properties 文件,这个文件就是 SpringBootSpringBootSpringBoot 自带的配置文件。但配置文件的位置并不是固定的。按照官方文档的介绍,配置文件可以放在以下四个位置,且优先级依次降低。
- 项目的根目录下的 configconfigconfig 文件夹中(这个文件夹默认不存在,需要的话要自己创建)
- 项目的根目录下
- resourcesresourcesresources 目录下的 configconfigconfig 文件夹中(这个文件夹默认不存在,需要的话要自己创建)
- resourcesresourcesresources 目录下(resources下就是classpath下resources下就是classpath下resources下就是classpath下)
SpringBootSpringBootSpringBoot 会依次加载这四个位置的配置文件,优先级高的配置会覆盖优先级低的配置,并形成互补配置。
当然,配置文件的位置也可以自己指定,但若不做相应的调整 ,SpringBootSpringBootSpringBoot 并不会去加载自定义的配置。我们可以在
设置spring.config.location=classpath:/路径/
,这样项目启动时就加载的是自定义路径下的配置文件了。
若是jar
包,我们可以通过下方命令修改路径。
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=路径
1.2 配置文件的名字
SpringBootSpringBootSpringBoot 默认加载的配置文件的名字都为 application.xxx
,但也可以是 application-{profile}.xxx
以应对多环境下不同的配置。但如有特殊需要,一定要修改application
这个名字,并且保证 SpringBootSpringBootSpringBoot 默认加载自定义的配置文件,我们可以参照修改配置文件路径的方式,只不过这次是 spring.config.name=名字
。
对于不同环境下的配置,若要激活对应的配置文件,需要在默认的配置文件 application.xxx
中加 spring.profiles.active=xxx
来激活。
1.3 配置文件的内容
- 字面量,如基本数据类型
- 对象
- 数组
- List,Set,Map等
- 占位符,如随机数 $${random.*}$
1.4 利用配置文件注入属性
- 基于 @Value@Value@Value 注解,给已经在容器中的 JavaBeanJavaBeanJavaBean 注入属性
@Component
public class Dog{
@Value("${dog.name}")
private String name;
//省略get/set方法
}
配置文件application.properties中
dog.name=BigDog
- 使用 @ConfigurationProperties@ConfigurationProperties@ConfigurationProperties 注解,给已经在容器中的 JavaBeanJavaBeanJavaBean 注入属性
@Component
@ConfigurationProperties(prefix = "dog")
public class Dog {
private String name;
//省略get/set方法
}
配置文件application.properties中
dog.name=BigDog
若我们需要给一个 BeanBeanBean 注入一个自定义的配置文件的属性,可以在 BeanBeanBean 上加 @PropertySource("classpath:配置文件")@PropertySource("classpath:配置文件")@PropertySource("classpath:配置文件") 注解,表明这个 BeanBeanBean 会加载我们指定的配置文件。
@PropertySource(value = {"classpath:dog.properties"})
@Component
@ConfigurationProperties(prefix = "dog")
public class Dog {
private String name;
//省略get/set方法
}
配置文件application.properties中
dog.name=BigDog
比较两种注入属性的方法
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
2.SpringBootSpringBootSpringBoot 自动装配原理
SpringBootSpringBootSpringBoot 自动装配的关键都在 @EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 注解中。
进入 @EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 中,可以看见它上面的注解
重点关注 @Import@Import@Import 注解。
这个注解是 SpringSpringSpring 中的注解,可以用来给容器中注入一个 BeanBeanBean ,而这里就是要给容器中注入一个AutoConfigurationImportSelectorAutoConfigurationImportSelectorAutoConfigurationImportSelector 类,这个类实现了 DeferredImportSelectorDeferredImportSelectorDeferredImportSelector 接口,这个接口继承了 ImportSelectorImportSelectorImportSelector 接口。
所以这个类必须重写String[] selectImports(AnnotationMetadata importingClassMetadata);
方法,而这个方法的功能,返回一个包含要注入到容器中的Bean的名称的数组,元数据由配置类提供(@Configuration@Configuration@Configuration)。
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
* @return the class names, or an empty array if none
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
这个方法底层扫描了所有META-INF/spring.factories
配置文件中的内容,所有需要创建的 BeanBeanBean 都在这里面,读取每个 starterstarterstarter 中的spring.factoriesspring.factoriesspring.factories 文件,封装成 propertiespropertiesproperties 对象,通过迭代器遍历取值,添加到容器中。
随便打开一个META-INF/spring.factories
内容,都是一个个自动配置类 xxxAutoConfigurationxxxAutoConfigurationxxxAutoConfiguration 。
以AopAutoConfigurationAopAutoConfigurationAopAutoConfiguration类为例
可以看见 @Configuration@Configuration@Configuration 注解,说明就是一个配置类,而这些配置类会提供元数据AnnotationMetadata importingClassMetadata
,也能看见 @ConditionalOnXXX@ConditionalOnXXX@ConditionalOnXXX注解,说明要满足某些条件,这个BeanBeanBean才能被加入容器中。
总结:借由@EnableAutoConfiguration@EnableAutoConfiguration@EnableAutoConfiguration 注解,找到META−INF/spring.factoriesMETA-INF/spring.factoriesMETA−INF/spring.factories文件,读取文件中的内容,而该文件里面都是一个个要被注入容器中的BeanBeanBean,满足条件后就被加入容器中,完成装配。
更多Java内容欢迎扫码关注我的公众号ACJavaBear,文章第一时间会发在上面。一起学Java吧