springboot启动流程源码分析(四)prepareEnvironment()

2023-05-27 0 605

    prepareEnvironment按字面上原意是预备自然环境,那究竟预备甚么自然环境呢?他们一起来渐渐看,其源代码如下表所示 private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment //建立并实用性适当的自然环境ConfigurableEnvironment environment = getOrCreateEnvironment(); //依照采用者实用性,实用性 environment控制系统自然环境configureEnvironment(environment, applicationArguments.getSourceArgs()); ConfigurationPropertySources.attach(environment); // 开启适当的H55N,当中两个关键的H55N ConfigFileApplicationListener 是读取工程项目实用性文件的H55N listeners.environmentPrepared(environment); //bindToSpringApplication存取自然环境bindToSpringApplication(environment); if (!this.isCustomEnvironment) { //自然环境切换 //假如environment.class和组件采用的EnvironmentClass()不完全一致 //所以转化成那样的 environment = newEnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } //将自然环境依附到PropertySourcesConfigurationPropertySources.attach(environment); return environment; }

①getOrCreateEnvironment()

springboot启动流程源码分析(四)prepareEnvironment()

ServletEnvironment private ConfigurableEnvironment getOrCreateEnvironment() { // 存在则直接返回 if (this.environment !=null) { return this.environment; } // 依照webApplicationType建立对应的Environment switch (this.webApplicationType) { case SERVLET: // 标准的Servlet自然环境,也是他们说的web自然环境 return new StandardServletEnvironment(); case REACTIVE: //REACTIVE自然环境 return new StandardReactiveWebEnvironment(); default: // 标准自然环境,非web自然环境 return newStandardEnvironment(); } }

②configureEnvironment(environment,applicationArguments.getSourceArgs());

springboot启动流程源码分析(四)prepareEnvironment()

protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { //增加类型切换服务-默认为true if (this.addConversionService) { //返回ApplicationConversionService实例ConversionService conversionService = ApplicationConversionService.getSharedInstance(); //设置类型切换服务environment.setConversionService((ConfigurableConversionService) conversionService); } //读取实用性源 及 命令行属性 configurePropertySources(environment, args); //实用性当前active的描述文件 configureProfiles(environment, args); }

a.configurePropertySources(environment, args);

springboot启动流程源码分析(四)prepareEnvironment()

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) { //调用AbstractEnvironment的getPropertySources()方法MutablePropertySources sources = environment.getPropertySources();     //假如this.defaultProperties不为null if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) { //所以添加defaultProperties到propertySources的末尾 sources.addLast(new MapPropertySource(“defaultProperties”, this.defaultProperties)); } //这里addCommandLineProperties默认为true 假如有命令行参数的数 if (this.addCommandLineProperties && args.length >0) { //name为:commandLineArgsString name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; //假如之前的MutablePropertySources中有name为commandLineArgs的PropertySource的话,则把当前命令行参数切换为CompositePropertySource类型,和原来的PropertySource进行合并,替换原来的PropertySource if(sources.contains(name)) { //假如sources中包含了”commandLineArgs”, //所以将其替换为”springApplicationCommandLineArgs”PropertySource<?> source = sources.get(name); //先将”commandLineArgs”修改为null, CompositePropertySource composite = newCompositePropertySource(name); //然后新增两个PropertySource //name为”springApplicationCommandLineArgs”, //source不变composite.addPropertySource(                    new SimpleCommandLinePropertySource(“springApplicationCommandLineArgs”, args)); composite.addPropertySource(source); //替换 sources.replace(name, composite); } else {        //假如之前没有name为commandLineArgs的PropertySource的话,则将其添加为MutablePropertySources中的第两个元素,注意了这里讲命令行参数添加为ConfigurableEnvironment中MutablePropertySources实例的第两个元素,且永远是第两个元素 sources.addFirst(newSimpleCommandLinePropertySource(args)); } } }

b.configureProfiles(environment, args);

springboot启动流程源码分析(四)prepareEnvironment()

//传入参数为StandardServletEnvironment和命令行参数 protected voidconfigureProfiles(ConfigurableEnvironment environment,String[] args) { //调用的是AbstractEnvironment的getActiveProfiles()方法 Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);profiles.addAll(Arrays.asList(environment.getActiveProfiles())); //设置environment的profileenvironment.setActiveProfiles(StringUtils.toStringArray(profiles)); }

③ConfigurationPropertySources.attach(environment);

springboot启动流程源码分析(四)prepareEnvironment()

//假如实用性了configurationProperties属性, 所以将其放在environment的propertySources的首部 public static void attach(Environment environment) { Assert.isInstanceOf(ConfigurableEnvironment.class, environment); //取得environment中的propertySourcesMutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources(); PropertySource<?> attached = sources.get(ATTACHED_PROPERTY_SOURCE_NAME); if (attached != null&& attached.getSource() != sources) { //假如存在的话,直接移除 sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);attached =null; } if (attached == null) { //将propertySources切换为SpringConfigurationPropertySources,放在首位sources.addFirst(new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME, newSpringConfigurationPropertySources(sources))); } }

④listeners.environmentPrepared(environment);

springboot启动流程源码分析(四)prepareEnvironment()

springboot启动流程源码分析(四)prepareEnvironment()

关于multicastEvent方法,详见springboot开启业务流程源代码预测(三)getRunListeners()中详解。 @Override  public void environmentPrepared(ConfigurableEnvironment environment) { this.initialMulticaster .multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment)); }

⑤bindToSpringApplication(environment);

springboot启动流程源码分析(四)prepareEnvironment()

protected void bindToSpringApplication(ConfigurableEnvironment environment) { try { //假如指定了main函数,所以会将当前自然环境存取到指定的SpringApplication中 Binder.get(environment).bind(“spring.main”, Bindable.ofInstance(this)); } catch (Exception ex) { throw new IllegalStateException(“Cannot bind to SpringApplication”, ex); } }

⑥convertEnvironmentIfNecessary(environment,deduceEnvironmentClass())

springboot启动流程源码分析(四)prepareEnvironment()

//自然环境切换StandardEnvironment convertEnvironmentIfNecessary(ConfigurableEnvironment environment, Class<? extends StandardEnvironment> type) { if(type.equals(environment.getClass())) { return (StandardEnvironment) environment; } //environment.getClass()不是StandardEnvironment的实例 return convertEnvironment(environment, type); } //自然环境切换 privateStandardEnvironment convertEnvironment(ConfigurableEnvironment environment, Class<? extends StandardEnvironment> type) {    //新建两个StandardEnvironment实例 //然后赋值 StandardEnvironment result = createEnvironment(type);result.setActiveProfiles(environment.getActiveProfiles()); result.setConversionService(environment.getConversionService());copyPropertySources(environment, result); return result; }

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务