Q: #17.2.4-1 | AlertServiceImpl是一个处理JMS消息的POJO,但是不依赖于JMS
A:
package com.habuma.spittr.alerts;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;
import com.habuma.spittr.domain.Spittle;
@Component(“alertService”)
public class AlertServiceImpl implements AlertService {
private JavaMailSender mailSender;
private String alertEmailAddress;
public AlertServiceImpl(JavaMailSender mailSender, String alertEmailAddress){
this.mailSender = mailSender;
this.alertEmailAddress = alertEmailAddress;
}
public void sendSpittleAlert(final Spittle spittle){ //发送Spittle提醒
SimpleMailMessage message = new SimpleMailMessage();
String spitterName = spittle.getSpitter().getFullName();
message.setFrom(“noreply@spitter.com”);
message.setTo(alertEmaillAddress);
message.setSubject(“New spittle from” + spitterName);
message.setTest(spitterName + “ says: “ + spittle.getText());
mailSender.send(message);
}
}
262
Q: #17.2.4-2 | 为了使用提醒服务,我们可以像下面那样配置JmsInvokerProxyFactoryBean:
A:
<bean id="alertService"
class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean"
p:connectionFactory-ref="connectionFactory"
p:queueName="spittle.alert.queue"
propp:serviceInterface="com.habuma.spittr.alerts.AlertService" />
263
Q: #17.2.4-3 | AMQP,是什么?
A: 高级消息队列协议(Advanced Message Queuing Protocol ,AMQP)得到了广泛的关注
264
Q: #17.3-1 | 实际上,AMQP具有多项JMS所不具备的优势
A: 首先,AMQP为消息定义了线路层(wire-level protocol)的协议,而JMS所定义的是API规范。JMS的API协议能够确保所有的实现都能通过通用的API来使用,但是并不能保证某个JMS实现所发送的消息能够被另外不同的JMS实现所使用。而AMQP的线路层协议规范了消息的格式,消息在生产者和消费者间传送的时候会遵循这个格式。这样AMQP在互相协作方面就要优于JMS——它不仅能跨不同的AMQP实现,还能跨语言和平台。
265
Q: #17.3-2 | 相比JMS,AMQP另外一个明显的优势在于它具有更加灵活和透明的消息模型
A: 使用JMS的话,只有两种消息模型可供选择:点对点和发布-订阅。这两种模型在AMQP当然都是可以实现的,但AMQP还能够让我们以其他的多种方式来发送消息,这是通过将消息的生产者与存放消息的队列解耦实现的。
266
Q: #17.3.1-1 | 在JMS中,通道有助于解耦消息的生产者和消费者,但是这两者依然会与通道相耦合
A: 生产者会将消息发布到一个特定的队列或主题上,消费者从特定的队列或主题上接收这些消息。通道具有双重责任,也就是传递数据以及确定这些消息该发送到什么地方,队列的话会使用点对点算法发送,主题的话就使用发布-订阅的方式。
267
Q: #17.3.1-2 | AMQP的生产者并不会直接将消息发布到队列中
A:
AMQP在消息的生产者以及传递信息的队列之间引入了一种间接的机制:Exchange。这种关系如图所示(在AMQP中,通过引入处理信息路由的Exchange,消息的生产者 与消息队列之间实现了解耦)
消息的生产者将信息发布到一个Exchange。Exchange会绑定到一个或多个队列上,它负责将信息路由到队列上。信息的消费者会从队列中提取数据并进行处理。
268
Q: #17.3.2-3 | AMQP定义了四种不同类型的Exchange,每一种都有不同的路由算法,这些算法决定了是否要将信息放到队列中。根据Exchange的算法不同,它可能会使用消息的routing key和/或参数,并将其与Exchange和队列之间binding的routing key和参数进行对比。(routing key可以大致理解为Email的收件人地址,指定了预期的接收者。)如果对比结果满足相应的算法,那么消息将会路由到队列上。否则的话,将不会路由到队列上。四种标准的AMQP Exchange如下所示。
A:
269
Q: #17.3.2-1 | Spring AMQP的rabbit命名空间包含了多个元素,用来创建队列、Exchange以及将它们结合在一起的binding
A:
<queue> --- 创建一个队列
<fanout-exchange> --- 创建一个fanout类型的Exchange
<header-exchange> --- 创建一个header类型的Exchange
<topic-exchange> --- 创建一个topic类型的Exchange
<direct-exchange> --- 创建一个direct类型的Exchange
<bindings><binding/></bindings> --- 元素定义一个或多个元素的集合。元素创建Exchange和队列之间的binding
270
Q: #17.3.2-2 | 如果你希望声明名为spittle.alert.queue的队列,只需要在Spring配置中添加如下的两个元素即可
A:
<admin connection-factory="connectionFactory"/>
<queue id="spittleAlertQueue" name="spittle.alerts" />