本文則將重點闡述context板塊的自動配置類,觀察其相關的特性並做相應的總結java
直接查看cloudcontext板塊下的spring.factories對應的EnableAutoConfiguration鍵值對spring
# AutoConfiguration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\ org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\ org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\ org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\ org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration
除了第一個自動配置類在前文有所說起,其他的四個能夠分爲步驟來進行一一的解析mvc
管理MVC的整個生命週期而暴露給外部的端點,LifecycleMvcEndpointAutoConfiguration的內部源碼仍是很簡單的ide
// 排在MVC配置類以後 @Configuration @AutoConfigureAfter(WebMvcAutoConfiguration.class) public class LifecycleMvcEndpointAutoConfiguration { // 註冊環境管理器EnvironmentManager @Bean @ConditionalOnMissingBean public EnvironmentManager environmentManager(ConfigurableEnvironment environment) { return new EnvironmentManager(environment); } }
EnvironmentManager類內含上下文環境變量ConfigurableEnvironment和事件分發器publisher,同時內部也暴露了JMX接口供外部調用。
總的來講也就是經過該類變動上下文屬性便會觸發EnvironmentChangeEvent事件,其中變動的屬性都將存入名爲manager的屬性集合中post
此處的刷新與前者的刷新屬性不一樣,其針對的是bean。並經過相應的刷新操做觸發RefreshScopeRefreshedEvent事件this
@Configuration @ConditionalOnClass(RefreshScope.class) // 可經過更改spring.cloud.refresh.enabled值來肯定是否讓該配置生效。默認爲true @ConditionalOnProperty(name = RefreshAutoConfiguration.REFRESH_SCOPE_ENABLED, matchIfMissing = true) @AutoConfigureBefore(HibernateJpaAutoConfiguration.class) public class RefreshAutoConfiguration { // 主要bean類 @Bean @ConditionalOnMissingBean(RefreshScope.class) public static RefreshScope refreshScope() { return new RefreshScope(); } }
其他的代碼沒貼出來,由於發現關鍵類就是此RefreshScope,其也暴露了JMX接口供外部調用來刷新bean(銷燬指定的bean)rest
此處的刷新針對的不是bean對象了,而是整個上下文context。code
@Configuration @ConditionalOnClass({EndpointAutoConfiguration.class, Health.class}) // 排在前者配置以後 @AutoConfigureAfter({ LifecycleMvcEndpointAutoConfiguration.class, RefreshAutoConfiguration.class}) // 導入類 @Import({ RestartEndpointWithIntegrationConfiguration.class, RestartEndpointWithoutIntegrationConfiguration.class, PauseResumeEndpointsConfiguration.class }) public class RefreshEndpointAutoConfiguration { }
優先對導入類做簡單的查看把xml
1.前兩個類其實都是爲了建立RestartEndpoint對象對象
// 端點名爲restart @Bean @ConditionalOnEnabledEndpoint @ConditionalOnMissingBean public RestartEndpoint restartEndpointWithoutIntegration() { return new RestartEndpoint(); }
而RestartEndpoint端點也暴露了JMX接口供外界調用直接刷新context,但無事件觸發,且其頭上有一個註解
@Endpoint(id = "restart", enableByDefault = false) public class RestartEndpoint implements ApplicationListener<ApplicationPreparedEvent> { }
可經過配置management.endpoint.${id}.enabled屬性來開關指定的端點,
也能夠經過@Endpoint註解中的屬性enableByDefault來指定(默認爲true);
全局的話也可經過環境屬性management.endpoints.enabled-by-default來指定。
由此得知RestartEndPoint端點默認是不開啓的
不過筆者發現此端點是ApplicationListener接口的實現類,但據筆者的認知範圍,只有在spring.factories文件中定義纔會被spring調用,那其又是怎麼被調用,確保其內部的context是有值的呢?待商榷!
2.PauseEndpoint端點和ResumeEndpoint端點的使用,但彼此都依賴RestartEndPoint端點,均是它的內部類。
@Configuration class PauseResumeEndpointsConfiguration { // 端點名爲pause @Bean @ConditionalOnBean(RestartEndpoint.class) @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public RestartEndpoint.PauseEndpoint pauseEndpoint(RestartEndpoint restartEndpoint) { return restartEndpoint.getPauseEndpoint(); } // 端點名爲resume @Bean @ConditionalOnBean(RestartEndpoint.class) @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public RestartEndpoint.ResumeEndpoint resumeEndpoint( RestartEndpoint restartEndpoint) { return restartEndpoint.getResumeEndpoint(); } }
經過這兩個端點來控制上下文的啓動與關閉,因而官方也暴露了相應的JMX接口供外部調用
而後對內部的Bean做下簡單的介紹
// 健康檢查類 // 可經過management.health.${id}.enable屬性來控制 @Bean @ConditionalOnMissingBean @ConditionalOnEnabledHealthIndicator("refresh") RefreshScopeHealthIndicator refreshScopeHealthIndicator(ObjectProvider<RefreshScope> scope, ConfigurationPropertiesRebinder rebinder) { return new RefreshScopeHealthIndicator(scope, rebinder); }
對環境變量的屬性可更改的端點則經過WritableEnvironmentEndpointAutoConfiguration來實現
@Configuration @ConditionalOnClass({ EnvironmentEndpoint.class, EnvironmentEndpointProperties.class }) @ConditionalOnBean(EnvironmentManager.class) @AutoConfigureBefore(EnvironmentEndpointAutoConfiguration.class) @AutoConfigureAfter(LifecycleMvcEndpointAutoConfiguration.class) @EnableConfigurationProperties({ EnvironmentEndpointProperties.class }) // 可經過management.endpoint.env.post.enabled屬性開關,默認爲true @ConditionalOnProperty(value = "management.endpoint.env.post.enabled", matchIfMissing = true) public class WritableEnvironmentEndpointAutoConfiguration { }
內部的Bean對象也就是暴露屬性的更改權限,有JMX方式也有MVC方式。
JMX方式
// 端點名爲env @Bean @ConditionalOnMissingBean @ConditionalOnEnabledEndpoint public WritableEnvironmentEndpoint environmentEndpoint(Environment environment) { WritableEnvironmentEndpoint endpoint = new WritableEnvironmentEndpoint(environment); String[] keysToSanitize = this.properties.getKeysToSanitize(); if (keysToSanitize != null) { endpoint.setKeysToSanitize(keysToSanitize); } return endpoint; }
MVC方式則引用了上文提到的EnvironmentManager對象。而且也引用了JMX方式中的WritableEnvironmentEndpoint對象,具體的使用則屬於cloud-actuator板塊,有興趣的讀者可自行分析
// 該端點以/env做爲端點入口 @Bean @ConditionalOnEnabledEndpoint public WritableEnvironmentEndpointWebExtension environmentEndpointWebExtension( WritableEnvironmentEndpoint endpoint, EnvironmentManager environment) { // 調用EnvironmentManager對象來操做上下文的環境變量 return new WritableEnvironmentEndpointWebExtension(endpoint, environment); }
無論是哪一種方式的調用,做用的對象是屬性。包含了單個屬性的更改、某個Environment的變量集合查看等等,範圍更爲寬廣。
cloudcontext板塊提供了針對環境屬性、bean對象、上下文等方式的刷新操做,均暴露JMX方式供外界調用;至於MVC方式有興趣的讀者可自行分析。
也就是刷新的入口在context板塊中已經獲得了相應的補充,至於擴展與相應的使用即是其他cloud板塊的範疇了。明白此點比較有利於後續對cloud的深刻了解