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.properties
與bootstrap.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
專案載入了兩種配置檔案,但實際上的ApplicationName
為application.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