文章目录
- 前言
- SpringBoot中的源码分析
- Spring中怎么使用yml作为配置文件
- 1.添加支持解析YAML的库(可选)
- 2.将properties文件转换为yml文件
- 3. 配置解析application.yml文件的PropertySourcesPlaceholderConfigurer:
- PropertySourcesPlaceholderConfigurer的作用
前言
推荐在项目中使用yml文件作为配置文件,因为yml可以配置对象,还可以单文件配置多环境。而传统properties配置多环境需要多文件。
YAML是JSON的超集,因此这是一种非常方便的格式,用于指定分层配置数据。它是所有编程语言的人性化数据序列化标准。YAML更易读,对于开发人员的读/写配置文件是有好处的。
YAML设计目标:
- YAML易于人类阅读。
- YAML数据在编程语言之间是可移植的。
- YAML匹配敏捷语言的本机数据结构。
- YAML具有一致的模型来支持通用工具。
- YAML支持单程处理。
- YAML具有表现力和可扩展性。
- YAML易于实施和使用。
SpringBoot中的源码分析
参考SpringBoot启动如何加载application.yml配置文件
- @EnableAutoConfiguration : 帮你实现自动配置的类,SpringBoot工程启动时,会运行一个SpringFactoriesLoader这个类, 加载META-INF/spring.factories配置类 (已经开启的) , 通过SpringFactoriesLoader 中的load方法, 以for循环的方式 ,一个一个加载配置。
- XxxAutoConfiguration: 自动配置类 : 给容器中添加组件。
- XxxProperties : 封装了配置文件的中的相关属性 : 给组件赋值。
每一个XxxAutoConfiguration类里面都包含了很多组件bean , 条件成立后都会加载到容器中,这个组件的属性从XxxProperties类中获取 , XxxProperties类中的每一个属性的值, 又和properties进行绑定。
Spring中怎么使用yml作为配置文件
Spring从4.1版本开始就提供了对YAML的支持,所以从Spring4.1开始要使用yml作为配置文件很简单,具体操作步骤如下。
1.添加支持解析YAML的库(可选)
<!-- SpringBoot就是使用的SnakeYAML库进行YAML支持 -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.17</version>
</dependency>
不知道为啥我亲测不导入这个库也行,但是Spring提供的YamlPropertiesFactoryBean和YamlMapFactoryBean都继承了Spring提供的YamlProcessor,且YamlProcessor需要依赖snakeyaml提供的Yaml类。
2.将properties文件转换为yml文件
可以使用“Convert YAML and Properties File”插件帮助我们快速将properties文件转换为yml文件,或将yml文件转换为properties文件。
首先要安装这个插件,Settings --> Plugins --> 搜索"Convert YAML and Properties File" --> Install。(我这个是已经安装成功了的截图)
然后选中要转换的文件,右键 --> convert。
就自动转换好了。
3. 配置解析application.yml文件的PropertySourcesPlaceholderConfigurer:
有两种方式
- 方式一:在Spring核心配置类中配置
//若在WebApplicationInitializer#getRootConfigClasses()中已声明该类是Spring核心配置类,此处就不必添加@Configuration注解
//@Configuration
@ComponentScan(basePackages = {"com.pxl.mvc"}, useDefaultFilters = true
, excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})})
//@PropertySource("classpath:application.properties")
public class RootConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(new ClassPathResource("application.yml"));
propertySourcesPlaceholderConfigurer.setProperties(yamlPropertiesFactoryBean.getObject());
return propertySourcesPlaceholderConfigurer;
}
}
注意:不能直接写为@PropertySource(“classpath:application.yml”),若这样写,结果是每一行被解析为一个k-v,因为该注解对应的解析器并不支持解析yml语法。
- 方式二:在spring.xml的<context:property-placeholder />中配置
<context:annotation-config/>
<bean id="yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources" value="classpath:application.yml"/>
</bean>
<context:property-placeholder properties-ref="yamlProperties"/>
PropertySourcesPlaceholderConfigurer的作用
- 什么时候会创建propertySourcesPlaceholderConfigurer-bean?
// 从ContextLoaderListener#contextInitialized()开始分析
contextInitialized:107, ContextLoaderListener (org.springframework.web.context)
initWebApplicationContext:326, ContextLoader (org.springframework.web.context)
configureAndRefreshWebApplicationContext:444, ContextLoader (org.springframework.web.context)
refresh:41010, AbstractApplicationContext (org.springframework.context.support)
__refresh:523, AbstractApplicationContext (org.springframework.context.support)
invokeBeanFactoryPostProcessors:681, AbstractApplicationContext (org.springframework.context.support)
invokeBeanFactoryPostProcessors:154, PostProcessorRegistrationDelegate (org.springframework.context.support)
getBean:202, AbstractBeanFactory (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:510, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBeanInstance:1023, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:1128, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:588, ConstructorResolver (org.springframework.beans.factory.support)
instantiate:162, SimpleInstantiationStrategy (org.springframework.beans.factory.support)
invoke:498, Method (java.lang.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
//创建propertySourcesPlaceholderConfigurer-bean
properties:31, RootConfig (com.pxl.mvc.config)
- 哪里会使用到我们注册的propertySourcesPlaceholderConfigurer-bean进行解析applicaiton.yml?
(待续…)
YamlPropertiesFactoryBean将加载YAML做为Properties和YamlMapFactoryBean将加载YAML做为Map,详情可参考Spring Boot Features