无法创建生产者以在 ActiveMQ 上发送消息

Unable to create producer to send messages on ActiveMQ

我正在学习 JMS 和不同类型的经纪人。我目前正在将 ActiveMQ (Artemis) 用于虚拟项目。

我目前的默认设置是 Artemis 运行。我可以转到管理控制台并查看队列和主题。 我现在正在创建 2 个基于 Java Spring 的应用程序;一种用于生产,一种用于消费。 我在那里看到的教程很少,但我得到了一个 NPE,我不确定 - 为什么,因为我相信我正确地自动装配了 bean。

这些是我的 classes:

主要class:

@SpringBootApplication
public class SpringJmsApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringJmsApplication.class, args);

    SendMessage send = new SendMessage("This is the test message");
  }
}

发件人:

public class Sender {

  private static final Logger LOGGER =
      LoggerFactory.getLogger(Sender.class);

  @Autowired
  private JmsTemplate jmsTemplate;

  public void send(String message) {
    LOGGER.info("sending message='{}'", message);
    jmsTemplate.convertAndSend("helloworld.q", message);
  }
}

发件人配置:

@Configuration
public class SenderConfig {

  @Value("${artemis.broker-url}")
  private String brokerUrl;

  @Bean
  public ActiveMQConnectionFactory senderActiveMQConnectionFactory() {
    return new ActiveMQConnectionFactory(brokerUrl);
  }

  @Bean
  public CachingConnectionFactory cachingConnectionFactory() {
    return new CachingConnectionFactory(
        senderActiveMQConnectionFactory());
  }

  @Bean
  public JmsTemplate jmsTemplate() {
    return new JmsTemplate(cachingConnectionFactory());
  }

  @Bean
  public Sender sender() {
    return new Sender();
  }
}

发送消息服务:

public class SendMessage {  
    @Autowired
    Sender sender;

    public SendMessage(String message){
        this.sender.send(message);
    }
}

所以基本上错误源于 SendMessage class,它无法自动装配发送者 bean 但我不确定为什么会发生此错误,因为发送者 bean 是在 SenderConfig class 因此 Spring 应该将其添加到其中 Spring container/Bean factory/application 上下文?

这是堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
    at com.codenotfound.jms.SendMessage.<init>(SendMessage.java:11)
    at com.codenotfound.SpringJmsApplication.main(SpringJmsApplication.java:16)

这是你的主 class 中的罪魁祸首。

SendMessage send = new SendMessage("This is the test message");

您是自己创建对象而不是从上下文中获取,Spring DI不会应用于我们自己创建的对象。

解决方案是,通过使用 @Component 注释将 SendMessage 标记为 spring 托管 bean,并从上下文中获取它。

您的问题并非源于 SendMessage class,这个 class 似乎没问题。

您的 NPE 是由您获取 SendMessage class 实例的方式引起的,也就是说,您并没有真正获取 @Bean,由 Spring 管理容器;相反,您是使用 new 关键字手动创建它,如:

SendMessage send = new SendMessage("This is the test message");

这在堆中分配了一个完整的 new 对象,它不会在 Spring 容器中结束,因此 → 不会由 Spring 管理,因此 → 它的字段 sender 不会是 @Autowired.