本文则将重点阐述context板块的自动配置类,观察其相关的特性并作相应的总结

直接查看cloudcontext板块下的spring.factories对应的EnableAutoConfiguration键值对

  1. # AutoConfiguration
  2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  3. org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
  4. org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
  5. org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
  6. org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
  7. org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration

除了第一个自动配置类在前文有所提及,其余的四个可以分为步骤来进行一一的解析

管理MVC的整个生命周期而暴露给外部的端点,LifecycleMvcEndpointAutoConfiguration的内部源码还是很简单的

  1. // 排在MVC配置类之后
  2. @Configuration
  3. @AutoConfigureAfter(WebMvcAutoConfiguration.class)
  4. public class LifecycleMvcEndpointAutoConfiguration {
  5. // 注册环境管理器EnvironmentManager
  6. @Bean
  7. @ConditionalOnMissingBean
  8. public EnvironmentManager environmentManager(ConfigurableEnvironment environment) {
  9. return new EnvironmentManager(environment);
  10. }
  11. }

EnvironmentManager类内含上下文环境变量ConfigurableEnvironment和事件分发器publisher,同时内部也暴露了JMX接口供外部调用。
总的来说也就是通过该类变更上下文属性便会触发EnvironmentChangeEvent事件

此处的刷新与前者的刷新属性不同,其针对的是bean。并通过相应的刷新操作触发RefreshScopeRefreshedEvent事件

  1. @Configuration
  2. @ConditionalOnClass(RefreshScope.class)
  3. // 可通过更改spring.cloud.refresh.enabled值来确定是否让该配置生效。默认为true
  4. @ConditionalOnProperty(name = RefreshAutoConfiguration.REFRESH_SCOPE_ENABLED, matchIfMissing = true)
  5. @AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
  6. public class RefreshAutoConfiguration {
  7. // 主要bean类
  8. @Bean
  9. @ConditionalOnMissingBean(RefreshScope.class)
  10. public static RefreshScope refreshScope() {
  11. return new RefreshScope();
  12. }
  13. }

其余的代码没贴出来,因为发现关键类就是此RefreshScope,其也暴露了JMX接口供外部调用来刷新bean

此处的刷新针对的不是bean对象了,而是整个上下文context。

  1. @Configuration
  2. @ConditionalOnClass({EndpointAutoConfiguration.class, Health.class})
  3. // 排在前者配置之后
  4. @AutoConfigureAfter({ LifecycleMvcEndpointAutoConfiguration.class,
  5. RefreshAutoConfiguration.class})
  6. // 导入类
  7. @Import({ RestartEndpointWithIntegrationConfiguration.class,
  8. RestartEndpointWithoutIntegrationConfiguration.class,
  9. PauseResumeEndpointsConfiguration.class })
  10. public class RefreshEndpointAutoConfiguration {
  11. }

优先对导入类作简单的查看把


1.前两个类其实都是为了创建RestartEndpoint对象

  1. // 端点名为restart
  2. @Bean
  3. @ConditionalOnEnabledEndpoint
  4. @ConditionalOnMissingBean
  5. public RestartEndpoint restartEndpointWithoutIntegration() {
  6. return new RestartEndpoint();
  7. }

而RestartEndpoint端点也暴露了JMX接口供外界调用直接刷新context,但无事件触发,且其头上有一个注解

  1. @Endpoint(id = "restart", enableByDefault = false)
  2. public class RestartEndpoint implements ApplicationListener<ApplicationPreparedEvent> {
  3. }

可通过配置management.endpoint.${id}.enabled属性来开关指定的端点,
也可以通过@Endpoint注解中的属性enableByDefault来指定(默认为true);
全局的话也可通过环境属性management.endpoints.enabled-by-default来指定。
由此得知RestartEndPoint端点默认是不开启的

不过我发现此端点是ApplicationListener接口的实现类,但我的印象中,只有在spring.factories文件中定义才会被spring调用,那其又是怎么被调用,确保其内部的context是有值的呢?待商榷!


2.PauseEndpoint端点和ResumeEndpoint端点的使用,但彼此依赖RestartEndPoint端点

  1. @Configuration
  2. class PauseResumeEndpointsConfiguration {
  3. // 端点名为pause
  4. @Bean
  5. @ConditionalOnBean(RestartEndpoint.class)
  6. @ConditionalOnMissingBean
  7. @ConditionalOnEnabledEndpoint
  8. public RestartEndpoint.PauseEndpoint pauseEndpoint(RestartEndpoint restartEndpoint) {
  9. return restartEndpoint.getPauseEndpoint();
  10. }
  11. // 端点名为resume
  12. @Bean
  13. @ConditionalOnBean(RestartEndpoint.class)
  14. @ConditionalOnMissingBean
  15. @ConditionalOnEnabledEndpoint
  16. public RestartEndpoint.ResumeEndpoint resumeEndpoint(
  17. RestartEndpoint restartEndpoint) {
  18. return restartEndpoint.getResumeEndpoint();
  19. }
  20. }


然后对内部的Bean作下简单的介绍

  1. // 健康检查类
  2. // 可通过management.health.${id}.enable属性来控制
  3. @Bean
  4. @ConditionalOnMissingBean
  5. @ConditionalOnEnabledHealthIndicator("refresh")
  6. RefreshScopeHealthIndicator refreshScopeHealthIndicator(ObjectProvider<RefreshScope> scope,
  7. ConfigurationPropertiesRebinder rebinder) {
  8. return new RefreshScopeHealthIndicator(scope, rebinder);
  9. }

对环境变量的属性可更改的端点则通过WritableEnvironmentEndpointAutoConfiguration来实现

  1. @Configuration
  2. @ConditionalOnClass({ EnvironmentEndpoint.class, EnvironmentEndpointProperties.class })
  3. @ConditionalOnBean(EnvironmentManager.class)
  4. @AutoConfigureBefore(EnvironmentEndpointAutoConfiguration.class)
  5. @AutoConfigureAfter(LifecycleMvcEndpointAutoConfiguration.class)
  6. @EnableConfigurationProperties({ EnvironmentEndpointProperties.class })
  7. // 可通过management.endpoint.env.post.enabled属性开关,默认为true
  8. @ConditionalOnProperty(value = "management.endpoint.env.post.enabled", matchIfMissing = true)
  9. public class WritableEnvironmentEndpointAutoConfiguration {
  10. }

内部的Bean对象也就是暴露属性的更改权限,有JMX方式也有MVC方式。


JMX方式

  1. // 端点名为env
  2. @Bean
  3. @ConditionalOnMissingBean
  4. @ConditionalOnEnabledEndpoint
  5. public WritableEnvironmentEndpoint environmentEndpoint(Environment environment) {
  6. WritableEnvironmentEndpoint endpoint = new WritableEnvironmentEndpoint(environment);
  7. String[] keysToSanitize = this.properties.getKeysToSanitize();
  8. if (keysToSanitize != null) {
  9. endpoint.setKeysToSanitize(keysToSanitize);
  10. }
  11. return endpoint;
  12. }

MVC方式则引用了上文提到的EnvironmentManager对象

  1. // 该端点以/env作为端点入口
  2. @Bean
  3. @ConditionalOnEnabledEndpoint
  4. public WritableEnvironmentEndpointWebExtension environmentEndpointWebExtension(
  5. WritableEnvironmentEndpoint endpoint, EnvironmentManager environment) {
  6. // 调用EnvironmentManager对象来操作上下文的环境变量
  7. return new WritableEnvironmentEndpointWebExtension(endpoint, environment);
  8. }

cloudcontext板块暴露了针对环境变量、bean对象、上下文等方式的刷新操作,并暴露JMX方式以及MVC方式供外界调用。具体可查看前文

版权声明:本文为question-sky原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/question-sky/p/10342654.html