美文网首页
spring 加载配置取不到值

spring 加载配置取不到值

作者: dozenx | 来源:发表于2019-12-12 22:53 被阅读0次

很奇怪的现象,debug之后发现spring也取到yaml文件里的值了.
但是调用appCtx.getEnvironment().getProperty(key)死活拿不到值.
于是细心观察甚至摸清了加载yaml过程
整个流程如下

进入
ConfigurableApplicationContext appCtx = SpringApplication.run(HolerApp.class, args);
        ServerUtil.setAppCtx(appCtx);
        String serverPort = ServerUtil.property(ServerConst.SERVER_PORT);
        log.info("Holer web server started on port " + serverPort);
        ServerContainer.getContainer().start();

run():1248, SpringApplication (org.springframework.boot)


    public static ConfigurableApplicationContext run(Class<?> primarySource,
            String... args) {
进入
        return run(new Class<?>[] { primarySource }, args);
    }
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
进入
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
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;
    }

environmentPrepared():54, SpringApplicationRunListeners (org.springframework.boot)

public void environmentPrepared(ConfigurableEnvironment environment) {
        for (SpringApplicationRunListener listener : this.listeners) {
  进入
            listener.environmentPrepared(environment);
        }
    }

environmentPrepared():75, EventPublishingRunListener (org.springframework.boot.context.event)

@Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(
                this.application, this.args, environment));
    }

@Override
    public void multicastEvent(ApplicationEvent event) {
        multicastEvent(event, resolveDefaultEventType(event));
    }
@Override
    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            Executor executor = getTaskExecutor();
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            }
            else {进入
                invokeListener(listener, event);
            }
        }
    }

invokeListener():165, SimpleApplicationEventMulticaster (org.springframework.context.event)

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                doInvokeListener(listener, event);
            }
            catch (Throwable err) {
                errorHandler.handleError(err);
            }
        }
        else {进入
            doInvokeListener(listener, event);
        }
    }



@SuppressWarnings({"unchecked", "rawtypes"})
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {进入
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            String msg = ex.getMessage();
            if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
                // Possibly a lambda-defined listener which we could not resolve the generic event type for
                // -> let's suppress the exception and just log a debug message.
                Log logger = LogFactory.getLog(getClass());
                if (logger.isDebugEnabled()) {
                    logger.debug("Non-matching event type for listener: " + listener, ex);
                }
            }
            else {
                throw ex;
            }
        }
    }

onApplicationEvent():163, ConfigFileApplicationListener (org.springframework.boot.context.config)


    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {进入
            onApplicationEnvironmentPreparedEvent(
                    (ApplicationEnvironmentPreparedEvent) event);
        }
        if (event instanceof ApplicationPreparedEvent) {
            onApplicationPreparedEvent(event);
        }
    }


加载完成后的environment长这样

private void onApplicationEnvironmentPreparedEvent(
            ApplicationEnvironmentPreparedEvent event) {
        List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
        postProcessors.add(this);
        AnnotationAwareOrderComparator.sort(postProcessors);
        for (EnvironmentPostProcessor postProcessor : postProcessors) {
            进入postProcessor.postProcessEnvironment(event.getEnvironment(),
                    event.getSpringApplication());
        }
    }

@Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
            SpringApplication application) {
进入
        addPropertySources(environment, application.getResourceLoader());
    }

具体的调用栈如下


2019-12-12 22:38:26屏幕截图.png
event = {ApplicationEnvironmentPreparedEvent@2281} "org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent[source=org.springframework.boot.SpringApplication@5276d6ee]"
 environment = {StandardServletEnvironment@1931} "StandardServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, MapPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yaml]'}]}"
  logger = {LogAdapter$Log4jLog@2343} 
  activeProfiles = {LinkedHashSet@2344}  size = 0
  defaultProfiles = {LinkedHashSet@2345}  size = 1
  propertySources = {MutablePropertySources@2346} "[StubPropertySource {name='servletConfigInitParams'}, StubPropertySource {name='servletContextInitParams'}, MapPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yaml]'}]"
   propertySourceList = {CopyOnWriteArrayList@2349}  size = 6
    0 = {PropertySource$StubPropertySource@2351} "StubPropertySource {name='servletConfigInitParams'}"
    1 = {PropertySource$StubPropertySource@2352} "StubPropertySource {name='servletContextInitParams'}"
    2 = {MapPropertySource@2353} "MapPropertySource {name='systemProperties'}"
    3 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@2354} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
    4 = {RandomValuePropertySource@2355} "RandomValuePropertySource {name='random'}"
    5 = {OriginTrackedMapPropertySource@3458} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yaml]'}"
     logger = {LogAdapter$Log4jLog@3469} 
     name = "applicationConfig: [classpath:/application.yaml]"
     source = {LinkedHashMap@3471}  size = 26
      0 = {LinkedHashMap$Entry@3475} "server.port" -> "8080"
      1 = {LinkedHashMap$Entry@3476} "server.use-forward-headers" -> "true"
      2 = {LinkedHashMap$Entry@3477} "server.servlet.session.timeout" -> "86400s"
      3 = {LinkedHashMap$Entry@3478} "spring.datasource.username" -> "root"
      4 = {LinkedHashMap$Entry@3479} "spring.datasource.password" -> "123456"
      5 = {LinkedHashMap$Entry@3480} "spring.datasource.driver-class-name" -> "com.mysql.cj.jdbc.Driver"
      6 = {LinkedHashMap$Entry@3481} "spring.datasource.url" -> "jdbc:mysql://localhost:3306/holer?createDatabaseIfNotExist=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC"
      7 = {LinkedHashMap$Entry@3482} "spring.datasource.platform" -> "mysql"
      8 = {LinkedHashMap$Entry@3483} "spring.datasource.data" -> "classpath:conf/holer-data.sql"
     propertyResolver = {PropertySourcesPropertyResolver@2347} 
 args = {String[0]@1295} 
 timestamp = 1576159995118
 source = {SpringApplication@1293}  

这个时候我回到我的app
ConfigurableApplicationContext appCtx = SpringApplication.run(HolerApp.class, args);
发现这里的appCtx尽然是个空对象 null

所以我觉得
public static void setAppCtx(ApplicationContext appCtx) {
appCtx = appCtx;
}
是不是被jvm理解错了
重命名为
public static void setAppCtx(ApplicationContext appCtx1) {
appCtx = appCtx1;
}
改成这样就ok了

相关文章

网友评论

      本文标题:spring 加载配置取不到值

      本文链接:https://www.haomeiwen.com/subject/lskuwctx.html