前言
本文我们来分析一下MessageChannelMetricWriter的实现.
MessageChannelMetricWriter
该类实现了MetricWriter–>更新消息通过MessageChannel的MetricWriter.发送的消息将Delta和Metric 作为消息体,并且带上了消息头–>metricName,说明是那个metric 需要处理
字段,构造器如下:
private final MessageChannel channel; public MessageChannelMetricWriter(MessageChannel channel) { this.channel = channel; }
其方法的实现都是通过MessageChannel来进行发现的,如下:
increment,代码如下:
public void increment(Delta<?> delta) { this.channel.send(MetricMessage.forIncrement(delta)); }
调用MetricMessage#forIncrement构建Message之后通过MessageChannel来发送
这里有必要介绍一下MetricMessage:
字段,构造器如下:
// 构造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; }
其暴露了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
其它方法和increment类似,如下:
public void set(Metric<?> value) { this.channel.send(MetricMessage.forSet(value)); } @Override public void reset(String metricName) { this.channel.send(MetricMessage.forReset(metricName)); }
自动装配:
自动装配声明在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 集成
首先在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>
在配置类中加入如下配置:
@Bean public MessageChannel metricsChannel() { return new DirectChannel(); } @Bean public IntegrationFlow test() { return IntegrationFlows.from("metricsChannel") .handle(CharacterStreamWritingMessageHandler.stdout()) .get(); }
在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 "操作成功"; }
启动后,访问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]
这只是1个案例,为了说明MessageChannelMetricWriter是如何工作的,实际项目中,我们可以该方式把数据放到数据库,发送到jms中等等.更多内容,请参考官方文档,链接如下: