1. 程式人生 > >Spring Cloud 2:Bootstrap

Spring Cloud 2:Bootstrap

Environment 端點

請求路徑

/env

資料來源

EnvironmentEndpoint

Controller 來源

EnvironmentMvcEndpoint

    @ActuatorGetMapping("/{name:.*}")
    @ResponseBody
    @HypermediaDisabled
    public Object value(@PathVariable String name) {
        if (!getDelegate().isEnabled()) {
            // Shouldn't happen - MVC endpoint shouldn't be registered when delegate's
            
// disabled return getDisabledResponse(); } return new NamePatternEnvironmentFilter(this.environment).getResults(name); }
Bootstrap的配置

SpringApplication.configurePropertySources進行載入

    /**
     * Add, remove or re-order any {@link PropertySource}s in this application's
     * environment.
     * 
@param environment this application's environment * @param args arguments passed to the {@code run} method * @see #configureEnvironment(ConfigurableEnvironment, String[]) */ 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 = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; 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)); } } }
bootstrap 屬性設定

application.propertiesbootstrap.properties同一級目錄下的時候,兩者都設定了 spring.application.name
此時訪問:http://localhost:8082/yang/env

獲取應用程式配置屬性:environment.getProperty("spring.application.name")
得到的實際是application.properties所設定的資訊:yang-cloud-example
也可以這樣獲取當前的應用程式名稱:
訪問:http://localhost:8082/yang/env/spring.application.name

專案載入了兩種配置檔案,但實際上的ApplicationNameapplication.properties載入的。

這是因為:Environment : PropertySources是1:1的關係,
PropertySources中的一個PropertySource

一旦載入了spring.application.name,之後的PropertySource就不會再去載入spring.application.name了。

即:第一個讀到的spring.application.name會覆蓋之後的。

如果註釋掉application.properties中的spring.application.name
啟動程式後訪問:http://localhost:8082/yang/env/spring.application.name

Bootstrap配置檔案

String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
可配置,預設bootstrap

注意:BootstrapApplicationListener的載入早於ConfigFileApplicationListener
所以在application.properties中設定spring.cloud.bootstrap.enabled=false是沒有效果的。
這是因為ConfigFileApplicationListener 的 Order = Ordered.HIGHEST_PRECEDENCE + 10 第十一位;

而 BootstrapApplicationListener 的Order=Ordered.HIGHEST_PRECEDENCE + 5第六位。

所以,如果需要設定spring.cloud.bootstrap.enabled=false,可以使用優先順序更高的事務去做,例如設定在命令列引數中。

Changing the Location of Bootstrap Properties

參考 BootstrapApplicationListener.java實現

public class BootstrapApplicationListener
        implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {

    public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap";

    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 5;

    public static final String DEFAULT_PROPERTIES = "defaultProperties";

    private int order = DEFAULT_ORDER;

    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment environment = event.getEnvironment();
        if (!environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class,
                true)) {
            return;
        }
        // don't listen to events in a bootstrap context
        if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) {
            return;
        }
        ConfigurableApplicationContext context = null;
        String configName = environment
                .resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");
        for (ApplicationContextInitializer<?> initializer : event.getSpringApplication()
                .getInitializers()) {
            if (initializer instanceof ParentContextApplicationContextInitializer) {
                context = findBootstrapContext(
                        (ParentContextApplicationContextInitializer) initializer,
                        configName);
            }
        }
        if (context == null) {
            context = bootstrapServiceContext(environment, event.getSpringApplication(),
                    configName);
        }
        apply(context, event.getSpringApplication(), environment);
    }

      // ignore others
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>sun.flower</groupId>
    <artifactId>yang-cloud-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>yang-cloud-example</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8
        </project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.M1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>
View Code