千家信息网

Springboot中ConfigFileApplicationListener的作用是什么

发表于:2024-10-04 作者:千家信息网编辑
千家信息网最后更新 2024年10月04日,今天就跟大家聊聊有关Springboot中ConfigFileApplicationListener的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文
千家信息网最后更新 2024年10月04日Springboot中ConfigFileApplicationListener的作用是什么

今天就跟大家聊聊有关Springboot中ConfigFileApplicationListener的作用是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

如下图1所示:

图1

ConfigFileApplicationListener实现了ApplicationListener,所以会收到Springboot的Event事件,如下List-1所示onApplicationEvent收到ApplicationEnvironmentPreparedEvent事件后,通过onApplicationEnvironmentPreparedEvent方法,获取spring.factories中的所有EnvironmentPostProcessor,并逐个调用EnvironmentPostProcessor的postProcessEnvironment方法。

List-1

@Overridepublic void onApplicationEvent(ApplicationEvent event) {        if (event instanceof ApplicationEnvironmentPreparedEvent) {                onApplicationEnvironmentPreparedEvent(                                (ApplicationEnvironmentPreparedEvent) event);        }        if (event instanceof ApplicationPreparedEvent) {                onApplicationPreparedEvent(event);        }}private void onApplicationEnvironmentPreparedEvent(                ApplicationEnvironmentPreparedEvent event) {        List postProcessors = loadPostProcessors();        postProcessors.add(this);        AnnotationAwareOrderComparator.sort(postProcessors);        for (EnvironmentPostProcessor postProcessor : postProcessors) {                postProcessor.postProcessEnvironment(event.getEnvironment(),                                event.getSpringApplication());        }}List loadPostProcessors() {        return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class,                        getClass().getClassLoader());}

List-1中onApplicationEnvironmentPreparedEvent方法里"postProcessors.add(this)",把当前实例也加入其中,所以来看看ConfigFileApplicationListener的postProcessEnvironment,如下List-2所示:

List-2

@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment,                SpringApplication application) {        addPropertySources(environment, application.getResourceLoader());}...protected void addPropertySources(ConfigurableEnvironment environment,                ResourceLoader resourceLoader) {        RandomValuePropertySource.addToEnvironment(environment);        new Loader(environment, resourceLoader).load();}

List-2中的Loader是个内部类,在ConfigFileApplicationListener中,Loader的构造方法如下List-3所示,从spring.factories中获得PropertySourceLoader,实现类有俩个,即PropertiesPropertySourceLoader和YamlPropertySourceLoader。

List-3

...Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {        this.environment = environment;        this.resourceLoader = (resourceLoader != null) ? resourceLoader                        : new DefaultResourceLoader();        this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(                        PropertySourceLoader.class, getClass().getClassLoader());}...

List-4

# PropertySource Loadersorg.springframework.boot.env.PropertySourceLoader=\org.springframework.boot.env.PropertiesPropertySourceLoader,\org.springframework.boot.env.YamlPropertySourceLoader

PropertiesPropertySourceLoader如下List-5,它支持的有properties和xml文件,并最终解析为Properties,封转到PropertiesPropertySource中。

List-5

public class PropertiesPropertySourceLoader implements PropertySourceLoader {     public String[] getFileExtensions() {        return new String[]{"properties", "xml"};    }    public PropertySource load(String name, Resource resource, String profile) throws IOException {        if (profile == null) {            Properties properties = PropertiesLoaderUtils.loadProperties(resource);            if (!properties.isEmpty()) {                return new PropertiesPropertySource(name, properties);            }        }        return null;    }}

YamlPropertySourceLoader如下List-6所示,支持的文件有yml和yaml,将yaml文件内容解析为map,之后封装到MapPropertySource。

List-6

public class YamlPropertySourceLoader implements PropertySourceLoader {    public String[] getFileExtensions() {        return new String[]{"yml", "yaml"};    }    public PropertySource load(String name, Resource resource, String profile) throws IOException {        if (ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", (ClassLoader)null)) {            YamlPropertySourceLoader.Processor processor = new YamlPropertySourceLoader.Processor(resource, profile);            Map source = processor.process();            if (!source.isEmpty()) {                return new MapPropertySource(name, source);            }        }        return null;        }        ...

从ConfigFileApplicationListener中可以看到,Springboot通过事件触发解析配置文件的操作(如下List-7中的listeners.environmentPrepared(environment)处),其中properties和xml文件解析到JDK的Properties中,之后加入到Springboot的evironment中;yml和yaml文件解析到JDK的map中,之后加入到evironment中。

List-7

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {        // Create and configure the environment        ConfigurableEnvironment environment = getOrCreateEnvironment();        configureEnvironment(environment, applicationArguments.getSourceArgs());        listeners.environmentPrepared(environment);        bindToSpringApplication(environment);        if (!this.isCustomEnvironment) {        environment = new EnvironmentConverter(getClassLoader())                        .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());        }        ConfigurationPropertySources.attach(environment);        return environment;}...

看完上述内容,你们对Springboot中ConfigFileApplicationListener的作用是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

0