SpringBoot中的配置文件(拓展)
如果有多个环境,配置文件需要根据环境来变化,只有一个配置文件就显的鸡肋了,每次变更环境的时候都需要修改一遍配置文件,两个还好,多了就相当麻烦了。
SpringBoot提供了多配置文件的用法,让环境的变化尽可能少的影响到配置文件的更改。
多配置文件
加载顺序
Spring会按以下顺序查找地址,如果有则优先使用前面的配置文件的属性,如果后面的文件有前面文件没有的属性,则会添加,否则忽略。
- file:./config/
- file:./
- classpath:/config/
- classpath:/
指定/添加默认加载地址
使用spring.config.location
来指定默认的加载地址。
如果spring.config.location 指定的值为: classpath:/custom-config/,file:./custom-config/,则系统会优先找这个文件。
如果使用spring.config.additional-location
来添加配置文件的加载地址。
命名格式
可以使用 application-{profile}.properties
来定义一个特殊的配置文件。特殊的这个配置文件如果调用,那么他总会覆盖掉默认的application.properties
文件中的内容。
比如使用application-dev.properties
作为开发环境的配置文件,在其中指定了服务端口8081.而在默认的application.properties
中指定的端口号为8080.那么,系统会使用哪个端口呢?
下面我使用yml文件作为例子(同properties文件)
1 | # application.yml文件中的内容 |
通过spring.profiles.active=dev(这时properties格式)。来特殊指定启用哪些配置文件。这里启用的是application-dev.properties
文件。
由控制台的输出结果可以看出,springBoot激活了名为dev
的配置文件及application-dev.properties
文件,并且更改端口为dev中指定的8081端口。
使用yaml文档块
yaml文件提供一种特性叫做文档块。使用三个-
来隔离配置信息
1 | # 默认的 |
使用文档块能够减少多个配置文件。与多个配置文件效果是等同的。
自动配置
其实在前面的文章中已经大概了解了SpringBoot
如何进行自动配置,但是仅仅停留在了EnableAutoConfiguration
注解的使用和浅层的解析上,这次需要更加深入的了解如何调用到自动配置类、我们如果想自己在配置文件中配置属性,该怎么去配置。
如何进行的自动配置
首先还是进入到SpringBootApplication
注解中
1 |
|
发现这里调用了EnableAutoConfiguration
注解。再点进这个注解中。
1 |
|
这里通过import注解使用了AutoConfigurationImportSelector类,这个类直接翻译过来叫做自动配置导入选择器。进入这个类中看。
1 | public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, |
这里我们可以看到AutoConfigurationImportSelector继承了DeferredImportSelector
这个类。这个类中需要实现的方法是void process(AnnotationMetadata metadata, DeferredImportSelector selector);
方法。
所以需要看AutoConfigurationImportSelector中是如何实现父类中定义的process
方法。
1 | public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) { |
通过getAutoConfigurationEntry
这个方法获取到所有的自动配置的信息。点进这个方法看是如何获取到的
1 | protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, |
通过getCandidateConfigurations来获取自动配置的全类名。
1 | protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { |
接着调用loadFactoryNames
获取自动配置类的List
1 | public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) { |
那么这个map的值是怎么形成的呢?
1 | // 在FACTORIES_RESOURCE_LOCATION中获取资源 |
下图是对result的debug结果,框中是所有的结果,但横线处是我们自动配置需要的。
结果在FACTORIES_RESOURCE_LOCATION(META-INF/spring.factories
)中可以找到.
这里的所有类都是可以自动配置到Spring的容器中。
如何根据自动配置类配置属性
进入到spring.factories
中进行查看所有autoConfigure类,用CacheAutoConfiguration举例,来分析以后想要配置关于cache的属性,怎么查找到这个配置属性,怎么配置到properties文件中。
直接点进类中发现有很多注解,一个个看
1 | //表示一个配置文件 |
其中EnableConfigtionProperties注解用来开启配置属性。
1 | // spring.cache就是在配置文件中使用的前缀 |
用cache中的redis对象为例子,如何去配置redis缓存。
其中指定了前缀,和中间的redis对象,所以redis的配置中的属性就应该是spring.cache.redis.xxx
.
1 | public static class Redis { |
比如需要配置不允许redis缓存空值,就需要配置cacheNullValues属性,所以可以在配置文件中写
1 | false = |
其他类型的自动配置类同理,每个自动配置类都配备一个xxxProperties.class
类进行属性的匹配,所以如果需要某个属性,则直接向对应的类中查找,找出前缀和属性名,则可直接找出完成的配置名称。
经过上面的分析,在也不用担心该如何配置配置文件了。
自定义SpringBoot Starter
实现自动配置
如果自行进行自动配置。主要实现的文件是:
xxxxAutoConfiguration
类xxxxProperties
类resources/META-INF/
下的spring.factories
文件中添加:org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.autocinfigure.xxxxAutoConfigure
在创建自动配置包前需要在pom文件中添加自动配置的包依赖。
1 | <dependencies> |
加载的基本过程:
- Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包
- 根据spring.factories配置加载AutoConfigure类
- 根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context