1。简介在实际的项目开发过程中,我们经常需要从代码中抽取一些变量,放到配置文件中,以更加统一灵活的管理服务配置信息。比如数据库、eureka、zookeeper、redis、mq、kafka等服务组件的连接参数配置,还有我们自定义的项目参数配置变量。当然,其实我们经常会根据现在的业务需求,自定义参数,注入到代码中,灵活使用!今天就来说说SpringBoot加载配置文件的几种方式!SpringBoot项目在使用中,默认先加载bootstrap.properties或bootstrap.yml这两个配置文件(这两个优先级最高);然后将加载application.properties或application.yml;如果配置了变量spring.profiles,同时会加载对应的application-{profile}.properties或者application-{profile}.yml文件,profile就是对应的环境变量,比如dev。如果没有配置,会加载profile=default的配置文件。虽然把配置项写在同一个配置文件里没有问题,但是很多时候我们还是希望分开写,这样会更清晰。比如zookeeper的配置写在zookeeper.properties,数据库相关的配置写在datasource.properties等,所以需要设置和加载外部配置文件!具体如何实现,一起来看看吧!2、代码实践2.1、通过@value注解实现参数加载@value注解可以轻松实现参数的注入!例如在application.properties文件中,配置一个变量key为config.name,值为zhangsan;//参数定义config.name=zhangsan然后在对应的类中,通过参数@值注入即可!@RestControllerpublicclassHelloController{@Value("${config.name}")私有字符串配置;@GetMapping("config")publicStringconfig(){returnJSON.toJSONString(config);}}使用@value注解注入配置,通常会有要求注解中的变量必须提前定义在application.properties文件中,否则启动会报错!当然,如果我们不想让它报错,我们可以给它一个默认的保存值xxx,例如:@Value("${config.name:xxx}")privateStringconfig;这样,SpringBoot项目启用就不会报错了!2.2.通过@ConfigurationProperties注解实现参数加载在某些场景下,@值注解并不能满足我们所有的需求。比如参数配置的数据类型是对象或者数组。这时候@ConfigurationProperties会是更好的选择!配置对象类型参数,例如在application.properties文件中。当我们要配置一个object类型的参数时,我们可以这样做!//参数定义config2.name=demo_1config2.value=demo_value_1然后,创建配置类Config2,用于将定义的变量映射到配置类@Component@ConfigurationProperties(prefix="config2")publicclassConfig2{publicStringname;公共字符串值;//...get,set}读取数据的方式也很简单,直接注入对应的类即可;@RestControllerpublicclassHelloController{@AutowiredprivateConfig2config2;@GetMapping("config2")publicStringconfig2(){returnJSON.toJSONString(config2);}}配置一个Map类型的参数比如在application.properties文件中,当我们要配置一个Map类型的参数时,我们可以这样做!//参数定义config3.map1.name=demo_id_1_nameconfig3.map1.value=demo_id_1_valueconfig3.map2.name=demo_id_2_nameconfig3.map2.value=demo_id_2_value然后,创建一个配置类Config3,将定义的变量映射到配置类中。@Component@ConfigurationProperties(prefix="config3")publicclassConfig3{privateMapmap1=newHashMap<>();privateMapmap2=newHashMap<>();//。..get,set}读取数据的方式类似!@RestControllerpublicclassHelloController{@AutowiredprivateConfig3config3;@GetMapping("config3")publicStringconfig3(){返回JSON.toJSONString(config3);}}配置一个List类型的参数比如在application.properties文件中,当我们要配置一个List类型的参数时,我们可以这样做!//参数定义config4.userList[0].enable=maillist_1_enableconfig4.userList[0].name=maillist_1_nameconfig4.userList[0].value=maillist_1_valueconfig4.userList[1].enable=maillist_2_enableconfig4.userList[1].name=maillist_2_nameconfig4.userList[1].value=maillist_2_valueconfig4.userList[2].enable=maillist_3_enableconfig4.userList[2].name=maillist_3_nameconfig4.userList[2].value=maillist_3_value然后创建一个配置类Config4将定义的变量映射到配置类。@Component@ConfigurationProperties(prefix="config4")publicclassConfig4{privateListuserList;publicListgetUserList(){返回用户列表;}publicvoidsetUserList(ListuserList){this.userList=userList;}}publicclassUserEntity{私有字符串启用;私有字符串名称;私有字符串值;//...get,set}读取数据,类似吧!@RestControllerpublicclassHelloController{@AutowiredprivateConfig4config4;@GetMapping("config4")publicStringconfig4(){返回JSON.toJSONString(config4);}}2.3。通过@PropertySource注解实现配置文件加载正如我们开头介绍的,很多时候,我们希望将配置文件分成例如zookeeper组件对应的服务配置文件是zookeeper.properties,redis对应的服务配置文件组件是redis.properties,等等。我们应该如何将这个自定义配置文件加载到Spring容器中呢?其实方法很简单,通过@PropertySource就可以实现!首先我们创建两个配置文件test.properties和bussiness.properties,内容如下!test.properties文件内容:aaa.a1=aa1123aaa.a2=aa2123aaa.a3=aa3123aaa.a4=aa4123bussiness.properties文件内容:bbbb.a1=bb1123bbbb.a2=bb2123bbbb.a3=bb3123bbbb.a4=bb4123加载配置文件即可关于SpringBoot启动类!@SpringBootApplication@PropertySource(value={"test.properties","bussiness.properties"})publicclassPropertyApplication{publicstaticvoidmain(String[]args){SpringApplication.run(PropertyApplication.class,args);}}读取数据的方式类似!@RestControllerpublicclassHelloController{@Value("${aaa.a2}")privateStringa2;@Value("${bbbb.a1}")privateStringbbbbA1;@GetMapping("a2")publicStringa2(){返回JSON.toJSONString(a2);}@GetMapping("bbbbA1")publicStringbbbbA1(){返回JSON.toJSONString(bbbbA1);如果我们只需要在业务中使用自定义配置文件的值,引入是没有问题的;但是如果项目启动的时候需要用到一些自定义变量,这个方法就会存在一些问题,原因如下:翻译过来的意思是说:虽然在@SpringBootApplication上使用@PropertySource看起来是一种方便简单的加载环境中自定义资源的方法,但是我们并不推荐,因为SpringBoot会刷新应用程序的程序上下文在环境之前准备好,使用@PropertySource定义的任何键加载得太晚,无法对自动配置产生任何影响。所以,如果有些参数是启动项变量,建议在application.properties或者application.yml文件中定义,这样是不会有问题的!或者,使用【自定义环境处理类】实现配置文件的加载!2.4.通过自定义环境处理类,加载配置文件的实现方法也很简单。首先创建一个实现了EnvironmentPostProcessor接口的类,然后自己加载配置文件。publicclassMyEnvironmentPostProcessorimplementsEnvironmentPostProcessor{@OverridepublicvoidpostProcessEnvironment(ConfigurableEnvironmentenvironment,SpringApplicationapplication){//自定义配置文件String[]profiles={"test.properties","business.properties","blog.yml"};//循环添加for(Stringprofile:profiles){//从classpath路径中查找文件Resourceresource=newClassPathResource(profile);//将其加载到一个PropertySource对象中,并将其添加到Environment中environment.getPropertySources().addLast(loadProfiles(resource));}}//加载单个配置文件}if(resource.getFilename().contains(".yml")){returnloadYaml(resource);}别的{返回负载属性(资源);}}/***加载属性格式的配置文件*@paramresource*@return*/privatePropertySourceloadProperty(Resourceresource){try{//从输入流加载一个属性对象Propertiesproperties=newProperties();properties.load(resource.getInputStream());返回新的PropertiesPropertySource(resource.getFilename(),properties);}catch(Exceptionex){thrownewIllegalStateException("加载配置文件失败"+resource,ex);}}/***加载yml格式的配置文件*@paramresource*@return*/privatePropertySourceloadYaml(Resourceresource){try{YamlPropertiesFactoryBeanfactory=newYamlPropertiesFactoryBean();factory.setResources(资源);//从输入流中加载一个Properties对象Propertiesproperties=factory.getObject();返回新的PropertiesPropertySource(resource.getFilename(),p财产);}catch(Exceptionex){thrownewIllegalStateException("加载配置文件失败"+resource,ex);接下来,在resources资源目录下,我们还需要创建一个文件META-INF/spring.factories,通过spi,将自定义环境处理类加载到Spring处理器中。项目启动时,会自动调用这个类!#启用我们的自定义环境处理类org.springframework.boot.env.EnvironmentPostProcessor=com。example.property.env.MyEnvironmentPostProcessor,自定义环境处理方式,相对来说更加灵活。首先编写一个支持读取属性和yml文件的通用配置文件解析类,然后注入到Spring容器中。基本上可以一劳永逸!2.5.最后介绍一下yml文件的读取。在上面,我们多以属性作为案例进行介绍。可能有人踩过坑,在项目中使用@PropertySource注解加载yml文件,结果启动时直接报错。原因是@PropertySource不支持直接解析yml文件,只能解析properties文件那么如果我想单独解析yml文件,又不想使用【自定义环境处理类】来读取文件,应该怎么处理呢?操作方法也很简单。以自定义blog.yml文件为例!blog.yml文件内容:pzblog:name:helloWorld然后,创建一个读取yml文件的配置类@ConfigurationpublicclassConfigYaml{/***载入YML格式的自定义配置文件*@返回*/@BeanpublicstaticPropertySourcesPlaceholderConfigurerproperties(){PropertySourcesPlaceholderConfigurer配置器=newPropertySourcesPlaceholderConfigurer();YamlPropertiesFactoryBeanyaml=newYamlPropertiesFactoryBean();yaml.setResources(newClassPathResource("blog.yml"));urconfigurer.setProperties(yaml.getObject;config()})读取数据的方式类似!@RestControllerpublicclassHelloController{@Value("${pzblog.name}")privateStringpzblogName;@GetMapping("pzblogName")publicStringpzblogName(){returnJSON.toJSONString(pzblogName);}}3.小结本文主要针对SpringBoot加载配置文件的几种实现方式,做了一个内容小结。如有疏漏,欢迎网友批评指正!四、参考1、SpringBoot官方文档