SpringBoot配置 在spring中我们都知道所有配置定义在配置文件application。yml中我们就可以通过注解获取到。 Spring中对所有配置管理都有一个统一的上层接口Environment 实现类图 可以看到实现类是非常多的。不过实际所有的配置获取都是封装在最上层的接口PropertyResolver中的 这里需要注意的是PropertyResolver的核心实现类PropertySourcesPropertyResolver 而PropertySourcesPropertyResolver中拥有的PropertySources最后使用的也还是PropertySource类,通过遍历PropertySource集合 而PropertySource最终是通过拥有一个泛型Tsource获取最终的属性 所以这里可以看到我们所有的资源都是一个PropertySource 需要注意的是,PropertySource之间是有优先级顺序的,如果有一个Key在多个PropertySource中都存在,那么在前面的PropertySource优先。 大致获取的原理这里引用apollo的一张图 这张图就是比较清晰的简单测试使用 springboot版本2。6。8 yaml配置一个name属性name:1214RestControllerpublicclassEnvironementController{AutowiredEValue({name})privateSGetMapping(name)publicStringenv(){System。out。println(name);returnenvironment。getProperty(name);}} 无论是使用Value还是Environment都能获取到我们的自定义属性 然后调用接口就能获取到我们配置中的属性了 SpringCloud自定义配置文件获取 在了解了上面的原理及基本使用之后我们可以就可以自定义配置文件了。核心思路就是通过读取文件然后加载到PropertySource中去。 而SpringCloud刚好提供类这方面的扩展,SpringCloud提供了PropertySourceLocator接口供我们加载自定义配置成PropertySource 我们这里只需要实现locate即可 按这个方式我们来自定义配置试试1。引入依赖propertiesproject。build。sourceEncodingUTF8project。build。sourceEncodingmaven。compiler。source1。8maven。compiler。sourcemaven。compiler。target1。8maven。compiler。targetspringcloud。version2021。0。2springcloud。versionspringboot。version2。7。0springboot。versionpropertiesdependencygroupIdorg。springframework。cloudgroupIdspringcloudcontextartifactIddependencydependencygroupIdorg。springframework。cloudgroupIdspringcloudstarterartifactIddependencydependencygroupIdorg。springframework。cloudgroupIdspringcloudstarterbootstrapartifactIddependencydependencygroupIdorg。springframework。bootgroupIdspringbootstarterwebartifactIddependencydependencyManagementdependenciesdependencygroupIdorg。springframework。bootgroupIdspringbootdependenciesartifactIdversion{springboot。version}versiontypepomtypescopeimportscopedependencydependencygroupIdorg。springframework。cloudgroupIdspringclouddependenciesartifactIdversion{springcloud。version}versiontypepomtypescopeimportscopedependencydependenciesdependencyManagement 注意springCloud2020版本后需要手动引入依赖springcloudstarterbootstrap2。自定义配置2。1自定义PropertySource,这里我们直接使用Spring提供的MapPropertySourcepackagecom。zou。importjava。util。Mimportorg。springframework。core。env。MapPropertySauthor:whdate:202271209:54description:publicclassZouMapPropertySourceextendsMapPropertySource{Createanew{codeMapPropertySource}withthegivennameand{codeMap}。paramnametheassociatednameparamsourcetheMapsource(without{codenull}valuesinordertogetconsistent{linkgetProperty}and{linkcontainsProperty}behavior)publicZouMapPropertySource(Stringname,MapString,Objectsource){super(name,source);}}2。2自定义PropertySourceLocatorpackagecom。zou。importjava。io。IOEimportjava。nio。charset。StandardCimportjava。nio。file。Fimportjava。nio。file。Pimportjava。util。HashMimportjava。util。Limportjava。util。Mimportorg。springframework。boot。json。JsonPimportorg。springframework。boot。json。JsonParserFimportorg。springframework。cloud。bootstrap。config。PropertySourceLimportorg。springframework。core。annotation。Oimportorg。springframework。core。env。Eimportorg。springframework。core。env。PropertySauthor:whdate:202271209:56description:Order(0)publicclassZouJsonPropertySourceLocatorimplementsPropertySourceLocator{OverridepublicPropertyS?locate(Environmentenvironment){returnnewZouMapPropertySource(ZouMapPropertySource,mapPropertySource());}privateMapString,ObjectmapPropertySource(){MapString,ObjectresultnewHashMap();JsonParserparserJsonParserFactory。getJsonParser();MapString,ObjectfileMapparser。parseMap(readFile());processNestMap(,result,fileMap);}读取配置文件zou。jsonreturnprivateStringreadFile(){ListStry{linesFiles。readAllLines(Paths。get(srcmainresourceszou。json),StandardCharsets。UTF8);}catch(IOExceptione){thrownewRuntimeException(e);}StringBuildersbnewStringBuilder();for(Stringline:lines){sb。append(line);}returnsb。toString();}privatevoidprocessNestMap(Stringprefix,MapString,Objectresult,MapString,ObjectfileMap){if(prefix。length()0){prefix。;}for(Map。EntryString,ObjectentrySet:fileMap。entrySet()){if(entrySet。getValue()instanceofMap){processNestMap(prefixentrySet。getKey(),result,(MapString,Object)entrySet。getValue());}else{result。put(prefixentrySet。getKey(),entrySet。getValue());}}}}2。3自定义配置BeanconfigConfiguration(proxyBeanMethodsfalse)publicclassZouConfiguration{BeanpublicZouJsonPropertySourceLocatorzouJsonPropertySourceLocator(){returnnewZouJsonPropertySourceLocator();}}2。4定义BootstrapConfiguration配置 在resources添加spring。factories配置文件org。springframework。cloud。bootstrap。BootstrapConfigurationcom。zou。config。ZouConfiguration3。测试 这里简单定义一个我们自己的配置文件zou。json {name:xiaozou} 定义一个测试controllerRestControllerRequestMapping(testv1)publicclassZouController{AutowiredEValue({name:1})privateSGetMapping(name)publicStringenv(){System。out。println(name);returnenvironment。getProperty(name);}} 可以看到我们自定义配置是生效了的 SpringCloud整合自定义配置还是比较容易的,核心还是自定义一个ZouJsonPropertySourceLocator然后加载PropertySource到Spring中。这里我们整合的是本地文件,其实如果要整合远程配置中心也是类似的,只不过获取文件就不是读取本地配置文件,而是通过http读取远程配置文件然后构造出一个PropertySource放入Spring容器中。后续有机会我们对nacos整合SpringCloud源码进行分析