springcloud情操陶冶-bootstrapContext(三)

本文則將重點闡述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生命週期端點自動配置類-刷新屬性

管理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

此處的刷新與前者的刷新屬性不一樣,其針對的是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

刷新端點自動配置類-刷新context

此處的刷新針對的不是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的深刻了解

相關文章
相關標籤/搜索