springcloud情操陶冶-bootstrapContext(三)

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

自动配置类

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

# 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的内部源码还是很简单的

// 排在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的属性集合中

刷新自动配置类-刷新Bean

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

@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)

刷新端点自动配置类-刷新context

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

@Configuration
@ConditionalOnClass({EndpointAutoConfiguration.class, Health.class})
// 排在前者配置之后
@AutoConfigureAfter({ LifecycleMvcEndpointAutoConfiguration.class,
        RefreshAutoConfiguration.class})
// 导入类
@Import({ RestartEndpointWithIntegrationConfiguration.class,
        RestartEndpointWithoutIntegrationConfiguration.class,
        PauseResumeEndpointsConfiguration.class })
public class RefreshEndpointAutoConfiguration {
}

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


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的深入了解

转载于:https://www.cnblogs.com/question-sky/p/10342654.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中,@Conditional注解和@AutoConfigureAfter注解是非常常用的注解,下面我来给你详细解析一下这两个注解。 ## @Conditional注解 @Conditional注解是Spring Boot中非常重要的一个注解,在Spring Boot中,很多自动配置都是通过@Conditional注解来实现的。 @Conditional注解可以根据满足某些条件来决定是否创建一个bean。比如,我们可以根据某个类是否存在来决定是否创建一个bean,具体示例如下: ```java @Configuration @Conditional(ExistClassCondition.class) public class MyConfiguration { @Bean public MyBean myBean() { return new MyBean(); } } public class ExistClassCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { try { Class.forName("com.example.MyClass"); return true; } catch (ClassNotFoundException e) { return false; } } } ``` 上面的代码中,我们定义了一个MyConfiguration类,并且在该类上加了@Conditional注解,该注解的参数是一个Condition的实现类ExistClassCondition。ExistClassCondition类中的matches方法返回true的条件是com.example.MyClass类存在。 这样,当com.example.MyClass类存在的时候,MyBean这个bean才会被创建。否则,MyBean这个bean不会被创建。 ## @AutoConfigureAfter注解 @AutoConfigureAfter注解也是Spring Boot中比较常用的注解之一,它可以用来控制自动配置的顺序。 比如,我们可以通过@AutoConfigureAfter注解来控制某个自动配置类在另一个自动配置类之后加载,具体示例如下: ```java @Configuration @AutoConfigureAfter(MyAutoConfiguration.class) public class MyAnotherAutoConfiguration { // ... } ``` 上面的代码中,我们定义了一个MyAnotherAutoConfiguration类,并且在该类上加了@AutoConfigureAfter注解,该注解的参数是MyAutoConfiguration.class。这样,在Spring Boot启动时,MyAutoConfiguration这个自动配置类会先于MyAnotherAutoConfiguration这个自动配置类被加载。 总结:@Conditional注解和@AutoConfigureAfter注解都是Spring Boot中非常实用的注解。通过@Conditional注解可以实现根据满足某些条件来决定是否创建一个bean,通过@AutoConfigureAfter注解可以控制自动配置类的加载顺序,这些都是我们在实际开发中非常常用的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值