Gosh! No one has ever even talked SpringBoot support configuration so smooth migration

Migratory

SpringBoot is native support for configuration migration, but did not see the official document describing this regard, only to see this module in the source code, spring-boot-properties-migrator, well I have not skipped. See this article that you can be regarded find the gems, I believe you read on down, will not help thumbs up, collection, attention.

effect

First you put the effect of attracting :)

From SpringBoot 2.0.0version, configuration service context, does not support server.context-path, but need server.servlet.context-pathto configure. But just add one of the following official dependence, it can support the use ofserver.context-path

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-properties-migrator</artifactId>
    </dependency>复制代码

server.context-pathThe corresponding attribute ServerProperties#contextPathdoes not exist in the Java code, server.servlet.context-path corresponding properties within the class Servletin the only, why add this dependence will be able to achieve such a magical effect it.

principle

SpringBoot configure the external migration of native support for the so-called migration, specifically refers to the property name corresponding to the configuration change, you can still use the original name of the configuration property. The spring-configuration-metadata.jsoninformation may be prompted to configure the secondary IDE, it can also be used to complete the configuration of the migration. Very simple.

Related articles: SpringBoot configuration prompts

By reading the code, the following information:

  1. Monitor ApplicationPreparedEventevents (ie: the environment has been prepared events), and collect the following information
  2. From classpath*:/META-INF/spring-configuration-metadata.jsonloading all configurations
  3. From the context of environmentthe filter arrangement in the tips (satisfies the condition:. 1 deprecation is not null, and the tips levelof error)
  4. Determining whether compatibility (compatibility condition see next section), the properties of the extracted compatible
  5. The value corresponds to replacementthe key, and attributes of the source name: migrate- formerly
  6. Configuration migrated 新属性源added to the environment, and 添加the properties of the original source 之前(high priority).
  7. Listen for events: ApplicationReadyEvent (application context is ready) or ApplicationFailedEvent (application failed to start), print the above steps to collect the legacy configuration information. To warn level print compatible configurations to print error level incompatible configurations

Configuration compatibility condition

Metadata defined typeAnalyzing

  1. If the old type, wherein one of the new type is null (the metadata is not specified), is not compatible with
  2. If the two types, compatible
  3. If the new type is Duration, while the old type is Long or Integer, it is compatible
  4. Other cases deemed incompatible
  5. From the get configuration information, in theory, support all SpringBoot configuration .environment

effect

Compatible effect: 弃用attribute (if it exists) and 替换the properties are in the configuration files of the deprecated attribute names corresponding value.

to sum up

Using configuration migration capabilities, you require the following steps:

  1. Introducing dependence: spring-boot-properties-migrator(support configuration migration), spring-boot-configuration-processor(generated metadata file, if you already have a full, does not need to rely on this)
  2. Metadata file spring-configuration-metadata.jsonin abandoned property name corresponding properties must have deprecation(at additional-spring-configuration-metadata.jsonadded, related articles: SpringBoot configuration prompts )
  3. deprecationIt needs to be given levelfor the error
  4. deprecation The need to specify replacement
  5. replacement Disposed in the corresponding attribute metadata file exists, attribute compatible with deprecated

The classic example of configuration context

Turning back to the beginning to show an example of configuration context.

# 配置 servlet 服务上下文
server:
  context-path: test复制代码

From SpringBoot 2.0.0version, does not support the above configuration, point to the configuration metadata file ( spring-configuration-metadata.json), find the following information:

{
  "properties": [
    {
      "name": "server.context-path",
      "type": "java.lang.String",
      "description": "Context path of the application.",
      "deprecated": true,
      "deprecation": {
        "level": "error",
        "replacement": "server.servlet.context-path"
      }
    },
    {
      "name": "server.servlet.context-path",
      "type": "java.lang.String",
      "description": "Context path of the application.",
      "sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties$Servlet"
    }复制代码

Alternatively property named: server.servlet.context-paththis property org.springframework.boot.autoconfigure.web.ServerPropertiesin, and can be found in the class, server.context-paththe corresponding attribute ServerProperties#contextPathis not present in the code, but within the class Servlethave, that is corresponding to server.servlet.context-path attribute only Have.

But it compatible configuration satisfies the conditions, why not actually use it like it compatible? In fact, because there is no dependence introduced , when the introduction of dependent, will find ways to configure this can work.

The two attributes are present exemplary

Code examples, see gitee.com/lw888/sprin...

1, rely on the introduction of

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-properties-migrator</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>复制代码

2, Java configuration here deliberately reserved abandoned property

@Data
@Configuration
@ConfigurationProperties(prefix = "my")
public class MyProperties {
  /** the project name */
  private String name;

  private App app;

  @Data
  public static class App {
    private String name;
  }
}复制代码

3, the metadata arranged, spring-configuration-metadata.json generated by the program, the custom configuration in additional-spring-configuration-metadata.jsonthe

{
  "properties": [
    {
      "name": "my.name",
      "type": "java.lang.String",
      "description": "the project name.",
      "deprecation": {
        "reason": "test the properties-migrator feature.",
        "replacement": "my.app.name",
        "level": "error"
      }
    },
    {
      "name": "my.app.name",
      "type": "java.lang.String",
      "sourceType": "com.lw.properties.migrator.config.MyProperties$App",
      "description": "the project name."
    }
  ]
}复制代码

4, the configuration file in the properties or yml

my:
  name: lw
  app:
    name: app复制代码

5, print configuration information

@Slf4j
@SpringBootApplication
public class PropertiesMigratorApplication {

  public static void main(String[] args) {
    ConfigurableApplicationContext context =
        SpringApplication.run(PropertiesMigratorApplication.class, args);
    MyProperties myProperties = context.getBean(MyProperties.class);
    log.info("myProperties.name:{}", myProperties.getName());
    log.info(
        "myProperties$app.name:{}",
        Optional.ofNullable(myProperties.getApp()).orElse(new App()).getName());
  }
}复制代码

6, print the following information:

2019-11-23 21:42:09.580 WARN 109408 --- [ main] o.s.b.c.p.m.PropertiesMigrationListener :The use of configuration keys that have been renamed was found in the environment:

Property source 'applicationConfig: [classpath:/application.yml]':Key: my.nameLine: 4Replacement: my.app.nameKey: server.context-pathLine: 2Replacement: server.servlet.context-path

Each configuration key has been temporarily mapped to its replacement for your convenience. To silence this warning, please update your configuration to use the new keys.
......... myProperties.name:lw
......... myProperties$app.name:lw
......... serverProperties$servlet.contextPath:/app

7, in effect attribute name resolve deprecated yml higher priority, with the new attribute deprecated this attribute value corresponding attribute name deprecated.

Reference material

SpringBoot 2.2.1.RELEASESource Public number: Yifei Come (focus on the Java domain knowledge in-depth study and orderly learning from the source to the principles of the system)

Yifei Come

Guess you like

Origin juejin.im/post/5ddc7a36e51d452347692cf4