我有两个SpringBoot应用程序,我在其中使用RabbitMQ在整个队列中传递消息。构建了一个应用程序来发送消息,而另一个则侦听已发送的消息。每个应用程序都包含一个@SpringBootApplication文件,该文件在属性级别具有一个@Autowired依赖项(一个应用程序具有发送者,另一个具有侦听器),每个应用程序都有一个单独的Spring @Configuration文件,该文件分别声明一个bean(一个具有发送者)还有一个接收器)。
由于某种原因,Sender应用程序的注入没有问题,但是,即使bean在我的应用程序上下文中,Receiver应用程序也没有在@Autowire进行注入。我正在使用示例应用程序作为向我们公司展示带有SpringBoot和微服务的RabbitMQ / SpringAMQP的一种方式。以下是发送方应用程序的代码,其后是接收方应用程序的代码。如果我将Receiver应用程序更改为使用Setter注入,则可以正常工作,我很好奇为什么其中一个有效而另一个无效。Receiver应用程序在其main方法中会在receive.receive()调用上爆炸,如下所示:
com.bettercloud.SpringAmqpApplication.main(SpringAmqpApplication.java:17)中的线程“主”中的异常java.lang.NullPointerException
接收器应用程序:
@SpringBootApplication public class SpringAmqpApplication { @Autowired static Recv receiver; public static void main(String[] args) throws IOException,InterruptedException { SpringApplication.run(SpringAmqpApplication.class, args); receiver.receive(); } } @Configuration public class Config { @Bean public Recv recv(){ return new Recv(); } } public class Recv { private final static String QUEUE_NAME = "task_queue"; public void receive() throws java.io.IOException, InterruptedException { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); System.out.println(" [*] Waiting for messages. To exit press CTRL+C"); channel.basicQos(1); QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(QUEUE_NAME, false, consumer); while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); String message = new String(delivery.getBody()); System.out.println(" [x] Received '" + message + "'"); doWork(message); System.out.println(" [x] Done"); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); } } private static void doWork(String task) throws InterruptedException { for (char ch: task.toCharArray()) { if (ch == '.') Thread.sleep(1000); } } }
发件人申请:
@SpringBootApplication public class SpringAmqpProducerApplication { @Autowired static Send sender; public static void main(String[] args) throws IOException { SpringApplication.run(SpringAmqpProducerApplication.class, args); sender.send(null); } } @Configuration public class Config { @Bean public Send send(){ return new Send(); } } public class Send { private final static String QUEUE_NAME = "task_queue"; public static void send(String[] argv) throws java.io.IOException { Connection connection = null; Channel channel = null; try { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); connection = factory.newConnection(); channel = connection.createChannel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); String message = getMessage(argv); channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes()); System.out.println(" [x] Sent '" + message + "'"); } finally { channel.close(); connection.close(); } } private static String getMessage(String[] strings){ if (strings == null || strings.length < 1) return "Hello World!"; return joinStrings(strings, " "); } private static String joinStrings(String[] strings, String delimiter) { int length = strings.length; if (length == 0) return ""; StringBuilder words = new StringBuilder(strings[0]); for (int i = 1; i < length; i++) { words.append(delimiter).append(strings[i]); } return words.toString(); } }
我认为注入根本不起作用,因为您尝试注入静态字段,而Spring不起作用。从您的字段(以及从您的方法中删除静态标识符),因为没有理由它们也是静态的),您的应用程序应该可以正常工作。
发送器可以工作,因为send方法是静态的,因此不需要对象即可调用该方法。