SpringBootApplication 类中的 Spring Autowire 在几乎相同的应用程序之间表现不同 [英] Spring Autowire inside of SpringBootApplication class is behaving differently between nearly identical applications

查看:60
本文介绍了SpringBootApplication 类中的 Spring Autowire 在几乎相同的应用程序之间表现不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个 SpringBoot 应用程序,我在其中使用 RabbitMQ 跨队列传递消息.一个应用程序用于发送消息,另一个应用程序侦听发送的消息.每个应用程序都包含一个 @SpringBootApplication 文件,该文件在属性级别具有一个 @Autowired 依赖项(一个应用程序具有发送者,另一个具有侦听器),并且每个应用程序都有一个单独的 Spring @Configuration 文件,每个文件声明一个 bean(一个具有发送者一个有接收器).

I have two SpringBoot applications where I'm using RabbitMQ to communicate messages across a queue. One application is built to send messages and the other listens for the sent messages. Each application consists of an @SpringBootApplication file which has one @Autowired dependency at the attribute level (one application has the sender the other has the listener) and each application has a separate Spring @Configuration file which declares one bean each (one has the sender and one has the receiver).

出于某种原因,Sender 应用程序没有注入问题,但是,即使 bean 在我的应用程序上下文中,Receiver 应用程序也没有在 @Autowire 处注入.我正在使用示例应用程序作为向我们公司展示带有 SpringBoot 和微服务的 RabbitMQ/SpringAMQP 的一种方式.下面是发送方应用程序和接收方应用程序的代码.如果我将 Receiver 应用程序更改为使用 Setter 注入,它就可以正常工作,我只是很好奇为什么其中一个有效而另一个无效.Receiver 应用程序在其主方法中调用receiver.receive() 时崩溃,如下所示:

For some reason, the Sender application has no issue with the injection, however, the Receiver application is not injecting at the @Autowire even though the bean is in my application context. I'm using the sample app as a means of demonstrating RabbitMQ/SpringAMQP with SpringBoot and microservices to our company. Below is the code of the Sender Application followed by the Receiver Application. If I change the Receiver application to use Setter injection it works just fine, I'm just very curious as to why one of these works and the other doesn't. The Receiver application blows up on receiver.receive() call in its main method like so:

线程main"中的异常java.lang.NullPointerException在 com.bettercloud.SpringAmqpApplication.main(SpringAmqpApplication.java:17)

Exception in thread "main" java.lang.NullPointerException at com.bettercloud.SpringAmqpApplication.main(SpringAmqpApplication.java:17)

接收器应用程序:

@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 中不起作用.从您的字段(以及您的方法,因为没有理由它们也是静态的)中删除静态标识符,您的应用程序应该可以正常工作.

I don't think the injection works at all, since your trying to inject static fields, which doesn't work with Spring. Remove the static identifier from your fields (and from your methods, because there is no reason they're static too) and your application should work fine.

发送方工作,因为发送方法是静态的,所以你不需要一个对象来调用该方法.

The sender works, because the send method is static, so you don't need an object to call the method.

这篇关于SpringBootApplication 类中的 Spring Autowire 在几乎相同的应用程序之间表现不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆