spring boot 源码解析42-MessageChannelMetricWriter详解

前言

本文我们来分析一下MessageChannelMetricWriter的实现.

MessageChannelMetricWriter

该类实现了MetricWriter–>更新消息通过MessageChannel的MetricWriter.发送的消息将Delta和Metric 作为消息体,并且带上了消息头–>metricName,说明是那个metric 需要处理

  1. 字段,构造器如下:

    private final MessageChannel channel;
    
    public MessageChannelMetricWriter(MessageChannel channel) {
        this.channel = channel;
    }
  2. 其方法的实现都是通过MessageChannel来进行发现的,如下:

    1. increment,代码如下:

      public void increment(Delta<?> delta) {
          this.channel.send(MetricMessage.forIncrement(delta));
      }

      调用MetricMessage#forIncrement构建Message之后通过MessageChannel来发送

      这里有必要介绍一下MetricMessage:

      1. 字段,构造器如下:

        // 构造Message中添加的头部
        private static final String METRIC_NAME = "metricName";
        
        // 构造Reset类型的消息时的消息体
        private static final String DELETE = "delete";
        
        private final Message<?> message;
        
        MetricMessage(Message<?> message) {
            this.message = message;
        }
      2. 其暴露了3个静态方法,其最终的实现都是调用其私有静态方法–>forPayload来实现的,如下:

        public static Message<?> forIncrement(Delta<?> delta) {
            return forPayload(delta.getName(), delta);
        }
        public static Message<?> forSet(Metric<?> value) {
            return forPayload(value.getName(), value);
        }
        public static Message<?> forReset(String metricName) {
            return forPayload(metricName, DELETE);
        }

        forPayload方法如下:

        private static Message<?> forPayload(String metricName, Object payload) {
            MessageBuilder<Object> builder = MessageBuilder.withPayload(payload);
            builder.setHeader(METRIC_NAME, metricName);
            return builder.build();
        }

        根据消息的类型,metricName 构建出对应的Message

    2. 其它方法和increment类似,如下:

      public void set(Metric<?> value) {
          this.channel.send(MetricMessage.forSet(value));
      }
      @Override
      public void reset(String metricName) {
          this.channel.send(MetricMessage.forReset(metricName));
      }
  3. 自动装配:

    自动装配声明在MetricsChannelAutoConfiguration中,如下:

    @Configuration
    @ConditionalOnClass(MessageChannel.class)
    @ConditionalOnBean(name = "metricsChannel")
    @AutoConfigureBefore(MetricRepositoryAutoConfiguration.class)
    public class MetricsChannelAutoConfiguration {
    
        @Bean
        @ExportMetricWriter
        @ConditionalOnMissingBean
        public MessageChannelMetricWriter messageChannelMetricWriter(
                @Qualifier("metricsChannel") MessageChannel channel) {
            return new MessageChannelMetricWriter(channel);
        }
    
    }

    当满足如下条件时MetricsChannelAutoConfiguration进行自动装配:

    • @ConditionalOnClass(MessageChannel.class) –> 在当前类路径下存在org.springframework.messaging.MessageChannel时生效
    • @ConditionalOnBean(name = “metricsChannel”)–> 当BeanFactory中存在id为metricsChannel的bean时生效

    当满足如下条件时会注册MessageChannelMetricWriter:

    • @ConditionalOnMissingBean–> BeanFactory中不存在MessageChannelMetricWriter类型的bean时生效

    同时由于在messageChannelMetricWriter方法中,对MessageChannel加上了@Qualifier(“metricsChannel”)注解,因此,在此时,会注入id为metricsChannel的MessageChannel

    由于默认情况下没有加入spring-integration相关的依赖,因此该配置不会生效

spring boot 集成

  1. 首先在pom文件中加入如下依赖:

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-integration</artifactId>
    </dependency>

    由于是demo,我们只需要将Channel中的message打印出来即可,因此加入如下依赖:

    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-stream</artifactId>
        <version>4.3.12.RELEASE</version>
    </dependency>
  2. 在配置类中加入如下配置:

    @Bean
    public MessageChannel metricsChannel() {
        return new DirectChannel();
    }
    
    @Bean
    public IntegrationFlow test() {
        return IntegrationFlows.from("metricsChannel")
                .handle(CharacterStreamWritingMessageHandler.stdout())
                .get();
    }
  3. 在controller中加入如下代码:

    @Autowired
    @Qualifier("messageChannelMetricWriter")
    private MetricWriter MessageChannelMetricWriter;
    
    @RequestMapping("/test-counter-channel")
    public String testCounterChannel() {
    
        MessageChannelMetricWriter.increment(new Delta<Number>("test-counter.count", 1, 
                new Date()));
    
        return "操作成功";
    }
  4. 启动后,访问http://127.0.0.1:8080/test-counter-channel 后就可以在控制台中有如下日志:

    Metric [name=test-counter.count, value=1, timestamp=Tue Jan 30 23:30:16 CST 2018]
  5. 这只是1个案例,为了说明MessageChannelMetricWriter是如何工作的,实际项目中,我们可以该方式把数据放到数据库,发送到jms中等等.更多内容,请参考官方文档,链接如下:

    spring-integration-reference

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值