springboot的condition为什么能获取到properties文件的内容

来源:互联网 发布:java如何实现线程 编辑:程序博客网 时间:2024/06/06 03:33

在spring-framework中,在使用Condtion的时候,取不到值。只能手动load一下properties,这种办法也是没有办法的办法。
而在springboot用这种方法,实现,不需要的,为什么不需要呢?

org.springframework.boot.context.config.ConfigFileApplicationListener就是这个类的。

这个类订阅了ApplicationEnvironmentPreparedEvent时间,字面上意思说是应用环境准备事件 ,它的触发条件是应用启动并且环境可以用与检查和修改的时候,。Environment这个名词在spring中用来表示存放properties文件的还是有系统默认的一些属性。

/** * Event published when a {@link SpringApplication} is starting up and the * {@link Environment} is first available for inspection and modification. * * @author Dave Syer */public class ApplicationEnvironmentPreparedEvent extends SpringApplicationEvent {

这个事件是在什么时候广播的呢?springBoot的入口方法里面

public ConfigurableApplicationContext run(String... args) {        StopWatch stopWatch = new StopWatch();        stopWatch.start();        ConfigurableApplicationContext context = null;        FailureAnalyzers analyzers = null;        configureHeadlessProperty();        SpringApplicationRunListeners listeners = getRunListeners(args);        listeners.starting();        try {            ApplicationArguments applicationArguments = new DefaultApplicationArguments(                    args);            //就是这里 就是这里 就是这里 它会调用广播器广播以上的那个ApplicationEnvironmentPreparedEvent 事件            ConfigurableEnvironment environment = prepareEnvironment(listeners,                    applicationArguments);            Banner printedBanner = printBanner(environment);            context = createApplicationContext();            analyzers = new FailureAnalyzers(context);            prepareContext(context, environment, listeners, applicationArguments,                    printedBanner);            refreshContext(context);            afterRefresh(context, applicationArguments);            listeners.finished(context, null);            stopWatch.stop();            if (this.logStartupInfo) {                new StartupInfoLogger(this.mainApplicationClass)                        .logStarted(getApplicationLog(), stopWatch);            }            return context;        }        catch (Throwable ex) {            handleRunFailure(context, listeners, analyzers, ex);            throw new IllegalStateException(ex);        }    }

既然有人广播了,所以我们这个ConfigFileApplicationListener监听器,在它获取到这个事件之后,做了什么呢?假设都已经知道了(不知道的可以看PropertyResourceConfigurer的源码),加载properties的具体实现其实是BeanFactoryPostProcessor,所以先从spring工厂加载器中加载并初始化这些后置处理器

List<EnvironmentPostProcessor> loadPostProcessors() {        return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class,                getClass().getClassLoader());    }

拿到之后,就很好办了,对它们排个序and执行它们。。。。为什么要排序呢,因为有的后置处理器是有一个优先级的概念的 实现了PriorityOrdered、Ordered,总不能让他们和普通的一起执行吧,如果不清楚,可以私信我。最好去看下源码。。

AnnotationAwareOrderComparator.sort(postProcessors);for (EnvironmentPostProcessor postProcessor : postProcessors) {            postProcessor.postProcessEnvironment(event.getEnvironment(),                    event.getSpringApplication());        }
阅读全文
0 0
原创粉丝点击