spring boot environment initialization process

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/yj1499945/article/details/86899170

Look at the most simple spring boot environment in some of what first spring boot version is 1.5.9

@RequestMapping(value = "/hello")
@RestController
public class HelloWorld {

    @Autowired
    private AbstractEnvironment environment;

    @RequestMapping(value = "/world", method = RequestMethod.GET)
    public String world() {

        System.out.println(environment);

        System.out.println(environment.getSystemEnvironment());

        System.out.println(environment.getSystemProperties());

        for (String s : environment.getActiveProfiles()){
            System.out.println(s);
        }

        System.out.println("qwe");

        for (String s : environment.getDefaultProfiles()){
            System.out.println(s);
        }

        return "qwe";

    }
    
}

Test code

StandardServletEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[MapPropertySource {name='server.ports'}, StubPropertySource {name='servletConfigInitParams'}, ServletContextPropertySource {name='servletContextInitParams'}, MapPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, PropertiesPropertySource {name='applicationConfig: [classpath:/application.properties]'}]}


This is the environment inside all variables, then take a look at where these environmental variables are generated. First, the method can be entered from the run can be seen prepareEnvironment method used to generate the environment.

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();
        this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
        listeners.environmentPrepared((ConfigurableEnvironment)environment);
        if (!this.webEnvironment) {
            environment = (new EnvironmentConverter(this.getClassLoader())).convertToStandardEnvironmentIfNecessary((ConfigurableEnvironment)environment);
        }

        return (ConfigurableEnvironment)environment;
    }

Just look at three methods can getOrCreateEnvironment, configureEnvironment, environmentPrepared, take a look at getOrCreateEnvironment

    private ConfigurableEnvironment getOrCreateEnvironment() {
        if (this.environment != null) {
            return this.environment;
        } else {
            return (ConfigurableEnvironment)(this.webEnvironment ? new StandardServletEnvironment() : new StandardEnvironment());
        }
    }

Here only a step, new StandardServletEnvironment (). Then take a look at some of what will be initialized

StandardServletEnvironment-> StandardEnvironment-> AbstractEnvironment. This is an inheritance, go initialization in the constructor AbstractEnvironment

   public AbstractEnvironment() {
        this.propertySources = new MutablePropertySources(this.logger);
        this.propertyResolver = new PropertySourcesPropertyResolver(this.propertySources);
        this.customizePropertySources(this.propertySources);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Initialized " + this.getClass().getSimpleName() + " with PropertySources " + this.propertySources);
        }

    }

customizePropertySources method to initialize, then found a way in StandardServletEnvironment

    protected void customizePropertySources(MutablePropertySources propertySources) {
        propertySources.addLast(new StubPropertySource("servletConfigInitParams"));
        propertySources.addLast(new StubPropertySource("servletContextInitParams"));
        if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
            propertySources.addLast(new JndiPropertySource("jndiProperties"));
        }

        super.customizePropertySources(propertySources);
    }

Here some initialization parameters of the servlet. There is also a method to call the parent class, let's look at the method in the parent class

  protected void customizePropertySources(MutablePropertySources propertySources) {
        propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties()));
        propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));
    }

   Found here initialize the system environment variables.

So far most of the initialization has been completed.

Then take a look configureEnvironment

   protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
        this.configurePropertySources(environment, args);
        this.configureProfiles(environment, args);
    }

Into the first method

    protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
        MutablePropertySources sources = environment.getPropertySources();
        if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
            sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
        }

        if (this.addCommandLineProperties && args.length > 0) {
            String name = "commandLineArgs";
            if (sources.contains(name)) {
                PropertySource<?> source = sources.get(name);
                CompositePropertySource composite = new CompositePropertySource(name);
                composite.addPropertySource(new SimpleCommandLinePropertySource(name + "-" + args.hashCode(), args));
                composite.addPropertySource(source);
                sources.replace(name, composite);
            } else {
                sources.addFirst(new SimpleCommandLinePropertySource(args));
            }
        }

    }

Here is the command-line parameters to initialize

Finally, look at the environmentPrepared, essentially ConfigFileApplicationListener class

When broadcasting, and calls onApplicationEnvironmentPreparedEvent

   private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
        List<EnvironmentPostProcessor> postProcessors = this.loadPostProcessors();
        postProcessors.add(this);
        AnnotationAwareOrderComparator.sort(postProcessors);
        Iterator var3 = postProcessors.iterator();

        while(var3.hasNext()) {
            EnvironmentPostProcessor postProcessor = (EnvironmentPostProcessor)var3.next();
            postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
        }

    }

Method entered postProcessEnvironment

   public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        this.addPropertySources(environment, application.getResourceLoader());
        this.configureIgnoreBeanInfo(environment);
        this.bindToSpringApplication(environment, application);
    }

Method entered addPropertySources

    protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
        RandomValuePropertySource.addToEnvironment(environment);
        (new ConfigFileApplicationListener.Loader(environment, resourceLoader)).load();
    }

Here RandomValuePropertySource added environment variables

Then he sent the last load .yml and the .properties file.

Into the load () method

       public void load() {
            this.propertiesLoader = new PropertySourcesLoader();
            this.activatedProfiles = false;
            this.profiles = Collections.asLifoQueue(new LinkedList());
            this.processedProfiles = new LinkedList();
            Set<ConfigFileApplicationListener.Profile> initialActiveProfiles = this.initializeActiveProfiles();
            this.profiles.addAll(this.getUnprocessedActiveProfiles(initialActiveProfiles));
            if (this.profiles.isEmpty()) {
                String[] var2 = this.environment.getDefaultProfiles();
                int var3 = var2.length;

                for(int var4 = 0; var4 < var3; ++var4) {
                    String defaultProfileName = var2[var4];
                    ConfigFileApplicationListener.Profile defaultProfile = new ConfigFileApplicationListener.Profile(defaultProfileName, true);
                    if (!this.profiles.contains(defaultProfile)) {
                        this.profiles.add(defaultProfile);
                    }
                }
            }

            this.profiles.add((Object)null);

            ConfigFileApplicationListener.Profile profile;
            label41:
            for(; !this.profiles.isEmpty(); this.processedProfiles.add(profile)) {
                profile = (ConfigFileApplicationListener.Profile)this.profiles.poll();
                Iterator var8 = this.getSearchLocations().iterator();

                while(true) {
                    while(true) {
                        if (!var8.hasNext()) {
                            continue label41;
                        }

                        String location = (String)var8.next();
                        if (!location.endsWith("/")) {
                            this.load(location, (String)null, profile);
                        } else {
                            Iterator var10 = this.getSearchNames().iterator();

                            while(var10.hasNext()) {
                                String name = (String)var10.next();
                                this.load(location, name, profile);
                            }
                        }
                    }
                }
            }

            this.addConfigurationProperties(this.propertiesLoader.getPropertySources());
        }

Look at the lowermost position is the location where the cycle required file, the order is such that row down. file: ./ config /, file: ./, classpath: / config /, classpath: /. name is the application, profile may be a "default", which correspond to the two application-default.yml.

Look at the inside of the load method

    private void load(String location, String name, ConfigFileApplicationListener.Profile profile) {
            String group = "profile=" + (profile == null ? "" : profile);
            String ext;
            if (!StringUtils.hasText(name)) {
                this.loadIntoGroup(group, location, profile);
            } else {
                for(Iterator var5 = this.propertiesLoader.getAllFileExtensions().iterator(); var5.hasNext(); this.loadIntoGroup(group, location + name + "." + ext, profile)) {
                    ext = (String)var5.next();
                    if (profile != null) {
                        this.loadIntoGroup(group, location + name + "-" + profile + "." + ext, (ConfigFileApplicationListener.Profile)null);
                        Iterator var7 = this.processedProfiles.iterator();

                        while(var7.hasNext()) {
                            ConfigFileApplicationListener.Profile processedProfile = (ConfigFileApplicationListener.Profile)var7.next();
                            if (processedProfile != null) {
                                this.loadIntoGroup(group, location + name + "-" + processedProfile + "." + ext, profile);
                            }
                        }

                        this.loadIntoGroup(group, location + name + "-" + profile + "." + ext, profile);
                    }
                }
            }

        }

There can be seen a this.loadIntoGroup (group, location + name + "." + Ext, profile) inside the for loop

application.properties is here initialized

 

Guess you like

Origin blog.csdn.net/yj1499945/article/details/86899170