問題描述
我想實現(xiàn) Spring AMQP 示例,以使用偵聽器發(fā)送和接收 Java 對象.我試過這個:
I want to implement Spring AMQP example for sending and receiving Java Objects using listener. I tried this:
發(fā)送 Java 對象
ConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
AmqpAdmin admin = new RabbitAdmin(connectionFactory);
admin.declareBinding(BindingBuilder.bind(new Queue(QUEUE_PROCESSING_TRANSACTION, false)).to(new TopicExchange(EXCHANGE_PROCESSING)).with(ROUTING_KEY_PROCESSING_TRANSACTION));
AmqpTemplate template = new RabbitTemplate(connectionFactory);
TransactionsBean obj = new TransactionsBean();
obj.setId(Long.valueOf(111222333));
接收并發(fā)送回另一個 Java 對象:
Receive and send Back another Java Object:
ConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
AmqpAdmin admin = new RabbitAdmin(connectionFactory);
admin.declareBinding(BindingBuilder.bind(new Queue(QUEUE_PROCESSING_TRANSACTION, false))
.to(new TopicExchange(EXCHANGE_PROCESSING)).with(ROUTING_KEY_PROCESSING_TRANSACTION));
AmqpTemplate template = new RabbitTemplate(connectionFactory);
TransactionsBean obj = (TransactionsBean) template.receiveAndConvert(QUEUE_PROCESSING_TRANSACTION);
System.out.println(" !!!!!!! Received id " + obj.getTransaction_id());
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueues(new Queue(QUEUE_PROCESSING_TRANSACTION, false));
container.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
// Receive here Java object and send back another object
}
});
你能告訴我如何在沒有復雜注釋的情況下擴展代碼,只需要簡單的偵聽器嗎?
Can you show me how to extend the code without complex annotations just simple listeners?
推薦答案
最簡單的方法是使用 @RabbitListener
- 使用 Spring Boot 時更容易,因為他會連接基礎(chǔ)設(shè)施 bean(模板、管理員等).
The simplest way is to use a @RabbitListener
- made even easier when using Spring Boot since he will wire up infrastructure beans (template, admin, etc).
@SpringBootApplication
public class So51009346Application {
public static final String QUEUE_PROCESSING_TRANSACTION = "q1";
public static void main(String[] args) {
SpringApplication.run(So51009346Application.class, args);
}
@Bean
public ApplicationRunner runner(RabbitTemplate template) {
return args -> {
ReplyObject reply = (ReplyObject) template.convertSendAndReceive("ex", "rk", new RequestObject());
System.out.println(reply);
};
}
@Bean
public Queue queue() {
return new Queue(QUEUE_PROCESSING_TRANSACTION);
}
@Bean
public TopicExchange te() {
return new TopicExchange("ex");
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(te()).with("rk");
}
}
class RequestObject implements Serializable {
private static final long serialVersionUID = 1L;
}
class ReplyObject implements Serializable {
private static final long serialVersionUID = 1L;
}
@Component
class Listener {
@RabbitListener(queues = So51009346Application.QUEUE_PROCESSING_TRANSACTION)
public ReplyObject process(RequestObject ro) {
return new ReplyObject();
}
}
如果您出于某種原因不想使用該注釋,您可以使用 MessageListenerAdapter 連接一個容器...
If you don't want to use that annotation for some reason, you can wire up a container using a MessageListenerAdapter...
@SpringBootApplication
public class So51009346Application {
public static final String QUEUE_PROCESSING_TRANSACTION = "q1";
public static void main(String[] args) {
SpringApplication.run(So51009346Application.class, args);
}
@Bean
public ApplicationRunner runner(RabbitTemplate template) {
return args -> {
ReplyObject reply = (ReplyObject) template.convertSendAndReceive("ex", "rk", new RequestObject());
System.out.println(reply);
};
}
@Bean
public SimpleMessageListenerContainer container(ConnectionFactory cf, Listener listener) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(cf);
container.setQueueNames(QUEUE_PROCESSING_TRANSACTION);
container.setMessageListener(new MessageListenerAdapter(listener, "process"));
return container;
}
@Bean
public Queue queue() {
return new Queue(QUEUE_PROCESSING_TRANSACTION);
}
@Bean
public TopicExchange te() {
return new TopicExchange("ex");
}
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(te()).with("rk");
}
}
class RequestObject implements Serializable {
private static final long serialVersionUID = 1L;
}
class ReplyObject implements Serializable {
private static final long serialVersionUID = 1L;
}
@Component
class Listener {
public ReplyObject process(RequestObject ro) {
return new ReplyObject();
}
}
當然,您可以自己連接容器,就像在您的問題中一樣,使用適配器,但通常最好讓 Spring 將其作為 @Bean
進行管理,否則您會錯過一些功能(例如失敗的事件發(fā)布,空閑容器).適配器獲取對您的請求/回復偵聽器的引用以及要調(diào)用的方法名稱.
You can, of course, wire up the container yourself, as in your question, using the adapter, but it's generally better to let Spring manage it as a @Bean
or you will miss some functionality (e.g. event publishing for failures, idle container). The adapter gets a reference to your request/reply listener and the method name to call.
這篇關(guān)于使用 Spring AMQP 接收和發(fā)送 Java 對象的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!