1 配置文件位置
springboot 启动会扫描以下位置的 application.properties 或者 application.yml 文件作为 Spring boot 的默认配置文件
–file:./config/
–file:./ 项目的跟路径,如果当前的项目有父工程,配置文件要放在父工程 的根路径
–classpath:/config/
–classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot 会从这四个位置全部加载主配置文件;互补配置;
2 指定配置文件名称
通过命令行参数 --spring.config.name
进行指定1~n个配置文件
# 指定一个
$ java -jar myproject.jar --spring.config.name=myproject
## 指定多个
$ java -jar myproject.jar
--spring.config.location=classpath:/default.properties,classpath:/override.prop
erties
松散绑定
属性文件中配置 说明
acme.my-project.person.first-name 羊肉串模式 case, 推荐使用
acme.myProject.person.firstName 标准驼峰模式
acme.my_project.person.first_name 下划线模式
ACME_MYPROJECT_PERSON_FIRSTNAME 大写下划线,如果使用系统环境时候推荐使用
⭐️ 在java文件中的前缀是否可以使用驼峰模式与版本有关,SpringBoot1.5.9 可以,2.2.2不行
绑定属性内部原理
setName:32, User (com.yh.stu.springboot.property.bean)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:358, BeanWrapperImpl$BeanPropertyHandler (o.s.beans)
processLocalProperty:467, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:290, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:278, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:699, RelaxedDataBinder$RelaxedBeanWrapper (o.s.boot.bind)
setPropertyValues:95, AbstractPropertyAccessor (o.s.beans)
applyPropertyValues:859, DataBinder (o.s.validation)
doBind:755, DataBinder (o.s.validation)
doBind:128, RelaxedDataBinder (o.s.boot.bind)
bind:740, DataBinder (o.s.validation)
doBindPropertiesToTarget:272, PropertiesConfigurationFactory (o.s.boot.bind)
bindPropertiesToTarget:240, PropertiesConfigurationFactory (o.s.boot.bind)
postProcessBeforeInitialization:330, ConfigurationPropertiesBindingPostProcessor
(o.s.b.context.properties)
postProcessBeforeInitialization:292, ConfigurationPropertiesBindingPostProcessor
(o.s.b.context.properties)
applyBeanPostProcessorsBeforeInitialization:409, AbstractAutowireCapableBeanFactory
(o.s.beans.factory.support)
initializeBean:1620, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
doCreateBean:555, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (o.s.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (o.s.beans.factory.support)
doGetBean:302, AbstractBeanFactory (o.s.beans.factory.support)
getBean:197, AbstractBeanFactory (o.s.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (o.s.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (o.s.context.support)
refresh:543, AbstractApplicationContext (o.s.context.support)
refresh:122, EmbeddedWebApplicationContext (o.s.boot.context.embedded)
refresh:693, SpringApplication (o.s.boot)
refreshContext:360, SpringApplication (o.s.boot)
run:303, SpringApplication (o.s.boot)
main:28, PropertyTestMainSpringApplication (com.yh.stu.springboot.property)
getBeanPostProcessors() = {ArrayList@5072} size = 12
0 = {ApplicationContextAwareProcessor@5137}
1 = {WebApplicationContextServletContextAwareProcessor@5138}
2 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@5139}
3 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@5140}
4 = {ConfigurationPropertiesBindingPostProcessor@4387}
5 = {MethodValidationPostProcessor@5141}
6 = {EmbeddedServletContainerCustomizerBeanPostProcessor@5142}
7 = {ErrorPageRegistrarBeanPostProcessor@5143}
8 = {CommonAnnotationBeanPostProcessor@5144}
9 = {AutowiredAnnotationBeanPostProcessor@5145}
10 = {RequiredAnnotationBeanPostProcessor@5146}
11 = {ApplicationListenerDetector@5147}
IDE中yml/properties文件无提示问题
需要加入如下的依赖
<!-- 为了让当前的实体类能在配置文件中有对应的提示-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
加入这个依赖后, 使用依赖提供的API在编译项目的时候处理@ConfigurationProperties注释的类, 生成您自己的配置元数据文件, 大家可以在你的项目中找到 ..\classes\META-INF\spring-configuration-metadata.json
文件 ,这个文件就是生成的元数据文件, IDE 基于这个文件给你提示了!!
注意:
有时候在idea中的加入了上面的依赖,但application.yml或者properties文件还是不提示, 这个时候文件的图标通常不是spring的绿色,此时应该在idea中设置 : shift + ctrl + alt + s
在输入框中输入你的文件名,然后确定就ok了 !
ConfigurationPropertiesBindingPostProcessor 进行属性绑定
测试程序
@SpringBootApplication
@EnableConfigurationProperties(User.class)
public class PropertyTestMainSpringApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication springApplication
= new SpringApplication(PropertyTestMainSpringApplication.class);
springApplication.setDefaultProperties(getDefaultProperties());
springApplication.run(args);
}
}
@ConfigurationProperties("dept.user")
public class User {
private long id;
private String name;
private Date birthday;
private List<String> toyNames;
private Set<String> socks;
// get/set 略....
}
application.yml
文件
server:
port: 7789
dept:
user:
name: name7789
User 类上没有标注@Component之类的注解,且@ConfigurationProperties也不是@Component派生的注解, Spring能将User对象纳入容器管理么?
从注解@EnableConfigurationProperties(User.class) 来看 ,好像Spring容器应该将其纳入其中进行管理了, 这里面的过程是什么样的?
带着疑问我们在User 的setName方法上打上断点 ,然后查看调用栈 , 看看这个过程到底是什么样的?
setName:37, User (com.yh.stu.springboot.property.bean)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
setValue:358, BeanWrapperImpl$BeanPropertyHandler (o.s.beans)
processLocalProperty:467, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:290, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:278, AbstractNestablePropertyAccessor (o.s.beans)
setPropertyValue:699, RelaxedDataBinder$RelaxedBeanWrapper (o.s.boot.bind)
setPropertyValues:95, AbstractPropertyAccessor (o.s.beans)
applyPropertyValues:859, DataBinder (o.s.validation)
doBind:755, DataBinder (o.s.validation)
doBind:128, RelaxedDataBinder (o.s.boot.bind)
bind:740, DataBinder (o.s.validation)
doBindPropertiesToTarget:272, PropertiesConfigurationFactory (o.s.boot.bind)
bindPropertiesToTarget:240, PropertiesConfigurationFactory (o.s.boot.bind)
postProcessBeforeInitialization:330, ConfigurationPropertiesBindingPostProcessor
(o.s.boot.context.properties)
// 这里调用了BeanPostProcessor类型的实例
// ConfigurationPropertiesBindingPostProcessor的postProcessBeforeInitialization方法
postProcessBeforeInitialization:292, ConfigurationPropertiesBindingPostProcessor
(o.s.boot.context.properties)
// 初始化规则之一在调用初始化方法前从容器中拿到所有的 BeanPostProcessor,调用其postProcessBeforeInitialization
applyBeanPostProcessorsBeforeInitialization:409, AbstractAutowireCapableBeanFactory
(o.s.beans.factory.support)
// 即在创建好bean后,会对bean进行一些初始化的工作
initializeBean:1620, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
doCreateBean:555, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (o.s.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (o.s.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (o.s.beans.factory.support)
doGetBean:302, AbstractBeanFactory (o.s.beans.factory.support)
// beanName是这样的:dept.user-com.yh.stu.springboot.property.bean.User
// 和普通beanName还是有区别的 ,这里就好奇这个beanName是如何生成并注册进来的
// 我们后续可以在注册BeanDefinition的地方打上断点看看
getBean:197, AbstractBeanFactory (o.s.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (o.s.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (o.s.context.support)
// 容器实例化 bean阶段
refresh:543, AbstractApplicationContext (o.s.context.support)
refresh:122, EmbeddedWebApplicationContext (o.s.boot.context.embedded)
refresh:693, SpringApplication (o.s.boot)
refreshContext:360, SpringApplication (o.s.boot)
run:303, SpringApplication (o.s.boot)
main:31, PropertyTestMainSpringApplication (com.yh.stu.springboot.property)