When I look through the source code, Springboot’s practice of getting configuration information is elegant and worth emulating. When introducing the Aware family interface, I actually mentioned the solution of obtaining configuration information. However, whether implementing EnvironmentAware interface or beans directly injected into Environment, they are essentially the same. It is difficult to obtain multiple configuration information.

// This article uses the following source code
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
org.springframework.boot.autoconfigure.http.HttpProperties
Copy the code

Start by creating the Properties file

The following three properties are defined with the prefix Spring. customize

Define a JavaBean based on properties

The @ConfigurationProperties annotation directly identifies the mapping between JavaBean attributes and configuration information. The prefix attribute of the annotation specifies the prefix of the configuration information to be mapped. Instead of specifying the prefix information as “spring.customize”, I specified “spring” in the code, where there is code-level dressiness. CustomizeProperties actually contains a static inner class called Customize. The official documentation (B3.1) clearly states its own attributes and their nested attributes.

package com.springboot.autoconfigure.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "spring")
public class CustomizeProperties {

    private final Customize customize = new Customize();

    public Customize getCustomize(a) {
        return customize;
    }

    public static class Customize {
        private String address;
        private String port;
        private boolean enable;

        public String getAddress(a) {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        public String getPort(a) {
            return port;
        }
        public void setPort(String port) {
            this.port = port;
        }

        public boolean isEnable(a) {
            return enable;
        }
        public void setEnable(boolean enable) {
            this.enable = enable; }}}Copy the code

Define the corresponding configuration class

@ EnableConfigurationProperties annotation is used to make using the @ ConfigurationProperties annotations in the class to take effect. Notice that the previous CustomizeProperties didn’t use the @Component annotation and can still be injected into the IOC container. The CustomizeProperties component is not allowed in the container when it is not in effect.

package com.springboot.autoconfigure.properties;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;

@Configuration
@EnableConfigurationProperties(CustomizeProperties.class)
public class CustomizeAutoConfiguration {

    private CustomizeProperties.Customize customize;

    /** * constructs injection when there is one and only one argument, * even if there is no explicit one@AutowiredYou can still assemble to the destination Bean */
    public CustomizeAutoConfiguration(CustomizeProperties customizeProperties) {
        this.customize = customizeProperties.getCustomize();
    }

    /** * Collect the obtained configuration information into the List * there is no point here, just for printing */
    @Bean
    public ArrayList arrayList (a) {
        ArrayList<Object> list = new ArrayList<>();
        list.add(customize.getAddress());
        list.add(customize.getPort());
        list.add(customize.isEnable());
        returnlist; }}Copy the code

Defining configuration classes

package com.springboot.autoconfigure.properties;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@PropertySource("classpath:application-dev.properties")
@ComponentScan("com.springboot.autoconfigure.properties")
public class Config {}Copy the code

Defining the startup class

package com.springboot.autoconfigure.properties;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.ArrayList;

public class MainCustomizeProperties {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                newAnnotationConfigApplicationContext(Config.class); ArrayList<Object> list = context.getBean(ArrayList.class); list.forEach(System.out::println); }}Copy the code

If the configuration information is obtained successfully, we can see the printed information.

spring-configuration-metadata.json

Spring-configuration-metadata. json is a json file that defines metadata. In fact, careful you should have found clues, the first picture configuration information below the wavy line unexpectedly reminded. This indicates that the three configurations are allowed to be linked. After the configuration information is associated with the corresponding JavaBean, the JavaBean also changes. The setter method corresponding to the property has a little icon prompt.

The configuration information is associated with the JavaBean, and the spring-configuration-metadata.json file is behind the red line. Detailed configuration rules are described in the official documents mentioned above.

Let me post my configuration information.

{
  "groups": [{"name": "spring"."type": "com.springboot.autoconfigure.properties.CustomizeProperties"."sourceType": "com.springboot.autoconfigure.properties.CustomizeProperties"
    },
    {
      "name": "spring.customize"."type": "com.springboot.autoconfigure.properties.CustomizeProperties$Customize"."sourceType": "com.springboot.autoconfigure.properties.CustomizeProperties"."sourceMethod": "getCustomize()"}]."properties": [{"name": "spring.customize.address"."type": "java.lang.String"."sourceType": "com.springboot.autoconfigure.properties.CustomizeProperties$Customize"
    },
    {
      "name": "spring.customize.enable"."type": "java.lang.Boolean"."sourceType": "com.springboot.autoconfigure.properties.CustomizeProperties$Customize"."defaultValue": false
    },
    {
      "name": "spring.customize.port"."type": "java.lang.String"."sourceType": "com.springboot.autoconfigure.properties.CustomizeProperties$Customize"}]."hints": []}Copy the code

In fact, if you really do not want to configure, coupled with dependencies, automatic generation can also.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true </optional>
</dependency>
Copy the code