厦门网站设计公司找哪家,陕西省和城乡建设厅网站,图片在线制作表情,呼和浩特做网站的公司Springboot默认加载application.yml原理以及扩展
SpringApplication.run(…)默认会加载classpath下的application.yml或application.properties配置文件。公司要求搭建的框架默认加载一套默认的配置文件demo.properties#xff0c;让开发人员实现“零”配置开发#xff0c;但…Springboot默认加载application.yml原理以及扩展
SpringApplication.run(…)默认会加载classpath下的application.yml或application.properties配置文件。公司要求搭建的框架默认加载一套默认的配置文件demo.properties让开发人员实现“零”配置开发但是前提如果开发人员在application.yml或application.properties文件中自定义配置则会“覆盖”默认的demo.properties文件按照Springboot外部化配置的特性优先使用先加载的只要demo.properties配置在application.yml或application.properties 配置之后加载到environment中即可。
一、SpirngApplication.run(…)源码分析
通过源码分析得知Springboot加载配置文件是利用Spring的事件机制通过EventPublishingRunListener取发布准备资源事件ApplicationEnvironmentPreparedEvent被ConfigFileApplicationListener监听到从而来实现资源的加载
具体源码如下 public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch new StopWatch();stopWatch.start();ConfigurableApplicationContext context null;CollectionSpringBootExceptionReporter exceptionReporters new ArrayList();configureHeadlessProperty();//这里是扩展的关键点SpringApplicationRunListeners listeners getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments new DefaultApplicationArguments(args);//这里是加载资源的关键ConfigurableEnvironment environment prepareEnvironment(listeners,applicationArguments);....}
//从方法名称来看就是准备environment的即配置信息private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// Create and configure the environmentConfigurableEnvironment environment getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());//这里默认EventPublishingRunListener发布ApplicationEnvironmentPreparedEvent事件//让监听器ConfigFileApplicationListener加载配置文件//这个listeners就是我们扩展的地方listeners.environmentPrepared(environment);bindToSpringApplication(environment);if (this.webApplicationType WebApplicationType.NONE) {environment new EnvironmentConverter(getClassLoader()).convertToStandardEnvironmentIfNecessary(environment);}ConfigurationPropertySources.attach(environment);return environment;}
SpirngApplication.run(...)方法中有个重要的扩展点方法getRunListeners(args);private SpringApplicationRunListeners getRunListeners(String[] args) {Class?[] types new Class?[] { SpringApplication.class, String[].class };return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));}//可扩展的关键点SpringFactoriesLoader//SpringFactoriesLoader会去加载META-INF/spring.factories文件并根据//type过滤出符合要求的类//比如这里的type对应的是SpringApplicationRunListenerprivate T CollectionT getSpringFactoriesInstances(ClassT type,Class?[] parameterTypes, Object... args) {ClassLoader classLoader Thread.currentThread().getContextClassLoader();// Use names and ensure unique to protect against duplicatesSetString names new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));ListT instances createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;}Springboot默认提供的META-INF/spring.factories这里就是我们可以扩展的地方
Run Listeners
org.springframework.boot.SpringApplicationRunListener\
org.springframework.boot.context.event.EventPublishingRunListener至此资源加载的大概流程就分析完了下面是我们的扩展
二、扩展——自定义加载配置文件demo.properties
通过上述源码分析得知只需要在项目中添加META-INF/spring.factories并配置SpringApplicationRunListener为我们自定义的来即可
1、在项目中的resources下创建META-INF/spring.factories
org.springframework.boot.SpringApplicationRunListener\
com.demo.module.ApplicatonEnvironDemoListener2、ApplicatonEnvironDemoListener的代码 package com.chyjr.hyboot.demo.module;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringApplicationRunListener;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.core.PriorityOrdered;import org.springframework.core.env.ConfigurableEnvironment;import org.springframework.core.env.MutablePropertySources;import org.springframework.core.env.PropertiesPropertySource;import org.springframework.core.env.PropertySource;import java.io.IOException;import java.util.Properties;public class ApplicatonEnvironDemoListener implements SpringApplicationRunListener,PriorityOrdered {private SpringApplication application;private String[] args;/*** 通过反射创建该实例对象的构造方法中的参数要加上如下参数*/public ApplicatonEnvironDemoListener(SpringApplication application,String[] args){this.application application;this.args args;}/*** 在准备环境之间调用* SpringApplication#run - listeners.starting();*/Overridepublic void starting() {System.out.println(starting-----);}Overridepublic void environmentPrepared(ConfigurableEnvironment environment) {Properties properties new Properties();try {//demo.properties就是我们自定义的配置文件extension是自定义目录properties.load(this.getClass().getClassLoader().getResourceAsStream(extension/demo.properties));PropertySource propertySource new PropertiesPropertySource(demo,properties);//PropertySource是资源加载的核心MutablePropertySources propertySources environment.getPropertySources();//这里添加最后propertySources.addLast(propertySource);} catch (IOException e) {e.printStackTrace();}}//省略其他方法.../*** 这里可以设置该配置文件加载的顺序在application.yml之前还是之后* EventPublishingRunListener#getOrder方法返回 “0”按照需求这里我们这是比0大* 即在application.yml之后加载这样在application.yml配置时可以“覆盖”my.yml* 这里用“覆盖”可能不合适意思到了就好*/Overridepublic int getOrder() {return 1;}}