Spring Integration Publisher

考虑一个假设的要求–您的应用程序中有一个服务类,并且想要捕获有关此服务调用的一些信息:

@Service
public class SampleBean {
 private static final Logger logger = LoggerFactory.getLogger(SampleBean.class);

 public Response call(Request request) {
  logger.info("SampleBean.call invoked");
  return new Response(true);
 }
}

AOP非常适合这种需求,它允许干净地捕获方法调用(切入点)周围的信息,并使用此信息进行一些处理(建议):

public class AuditAspect {
 private static final Logger logger = LoggerFactory.getLogger(AuditAspect.class);
 @Pointcut("execution( * core.SampleBean.call(model.Request)) && args(r)")
 public void beanCalls(Request r){}

 @Around("beanCalls(r)")
 public Object auditCalls(ProceedingJoinPoint pjp, Request r) {
     logger.info("Capturing request: " + r);
  try{
   Object response = pjp.proceed();
   logger.info("Capturing response: " + response);
   return response;
  }catch(Throwable e) {
   throw new RuntimeException(e);
  }
 }
}

这似乎足够好。 现在,如果我想立即将响应返回给客户端,但继续处理方法调用的上下文,该怎么办?我们可以使用ThreadPool将Advice的逻辑放在单独的线程中。 现在让我增加另一层复杂性,如果我们要绝对确保不丢失上下文,该怎么办?一个好的方法是将方法调用的上下文保留在JVM之外,通常像RabbitMQ和ActiveMQ这样的消息传递提供者将非常适合

考虑到这些额外的要求,一个更简单的解决方案(尤其是在正在使用消息传递场景的情况下)将使用Spring Integration。 让我们首先定义一个新的Spring Integration应用程序上下文:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <annotation-config/>

    <channel id="tobeprocessedlater"/>

    <logging-channel-adapter channel="tobeprocessedlater" log-full-message="true"/>

</beans:beans>

它只是具有一个通道的定义,以及一个出站适配器,该适配器从该通道读取并记录完整的消息。 为了捕获对SampleBean的调用的上下文,可以将Publisher注释添加到SampleBean的相关方法,该方法将“东西”定向到添加到注释的通道。

@Service
public class SampleBean {
 private static final Logger logger = LoggerFactory.getLogger(SampleBean.class);

 @Publisher(channel = "tobeprocessedlater")
 public Response call(@Header("request") Request request) {
  logger.info("SampleBean.call invoked");
  return new Response(true);
 }
}

通过附加注释指定将什么“东西”发送到此“ tobeprocessedlater”信道–默认情况下,该方法的返回值发送到该信道,此外,我还使用@Header注释标记了请求,这将使请求作为响应消息的头发送。 为了完整起见,集成上下文具有一个<annotation-config />标记,该标记注册寻找@Publisher注释的相关组件,并在发现一个组件时将其织入要执行的其他操作中。

如果现在执行此代码,则输出将遵循以下几行:

core.SampleBean - SampleBean.call invoked
o.s.integration.handler.LoggingHandler - [Payload=Response{success=true}][Headers={request=RequestType1{attr='null'}, id=52997b10-dc8e-e0eb-a82a-88c1df68fca5, timestamp=1389268390212}]

现在,为了满足第一个需求,在单独的执行线程中处理建议(在本例中为日志记录):

只需更改配置即可完成! –在此示例中,我选择使用执行者通道,而不是将消息发布到直接通道,而是将其发布为可以缓冲消息或使用执行程序来分派消息的通道类型:

<channel id="tobeprocessedlater">
        <dispatcher task-executor="taskExecutor"/>
    </channel>

现在,为了增加将异步消息处理发布到外部消息传递提供程序(并稍后处理消息)以使其更加可靠的要求,让我通过将消息发布到RabbitMQ进行演示,代码更改再次是纯配置,代码中没有任何变化!:

<channel id="tobeprocessedlater"/>

    <int-amqp:outbound-channel-adapter amqp-template="amqpTemplate" channel="tobeprocessedlater"  />

消息传递接收器可以是任何东西–数据库,文件系统,ActiveMQ,而需要进行的更改是纯配置。

参考: all和其他博客中的JCG合作伙伴 Biju Kunjummen的Spring Integration Publisher

翻译自: https://www.javacodegeeks.com/2014/01/spring-integration-publisher.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值