You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Dropwizard客户端应用中ActiveMQ配置及JMS主题监听问题咨询

嘿,我来帮你搞定Spring Dropwizard里配置ActiveMQ并实现主题监听的问题!毕竟Dropwizard的配置逻辑和Spring Boot不太一样,咱们一步步来,尽量最小改动:

1. 先定义Dropwizard的配置类

Dropwizard不像Spring Boot那样自动读取spring.*前缀的配置,你需要创建自己的配置类来映射config.yml里的内容。创建一个继承自io.dropwizard.Configuration的类:

import io.dropwizard.Configuration;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotEmpty;

public class AppConfig extends Configuration {
    // 绑定yml里的activemq节点
    @JsonProperty("activemq")
    private ActiveMQSettings activeMQSettings = new ActiveMQSettings();

    public ActiveMQSettings getActiveMQSettings() {
        return activeMQSettings;
    }

    // 内部类对应activemq的具体配置项
    public static class ActiveMQSettings {
        @JsonProperty("broker-url")
        @NotEmpty
        private String brokerUrl = "tcp://localhost:61616";

        @JsonProperty("cache-enabled")
        private boolean cacheEnabled = false;

        // Getters & Setters
        public String getBrokerUrl() { return brokerUrl; }
        public void setBrokerUrl(String brokerUrl) { this.brokerUrl = brokerUrl; }
        public boolean isCacheEnabled() { return cacheEnabled; }
        public void setCacheEnabled(boolean cacheEnabled) { this.cacheEnabled = cacheEnabled; }
    }
}

2. 编写config.yml的正确配置

现在把你的ActiveMQ配置放在顶层的activemq节点下,这样Dropwizard才能读取到:

# config.yml
activemq:
  broker-url: tcp://0.0.0.0:61616
  cache-enabled: false

# 其他Dropwizard默认配置(比如server、logging等)
server:
  applicationConnectors:
    - type: http
      port: 8080
  adminConnectors:
    - type: http
      port: 8081

3. 配置Spring的JMS Bean(核心步骤)

Dropwizard没有Spring Boot的自动配置,所以咱们需要手动创建ActiveMQ相关的Bean,实现和Spring Boot一样的效果:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;

@Configuration
public class JmsConfiguration {

    private final AppConfig.ActiveMQSettings activeMQSettings;

    // 通过构造注入Dropwizard的配置
    public JmsConfiguration(AppConfig.ActiveMQSettings activeMQSettings) {
        this.activeMQSettings = activeMQSettings;
    }

    // 创建ActiveMQ连接工厂
    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
        factory.setBrokerURL(activeMQSettings.getBrokerUrl());

        // 对应Spring Boot里的spring.jms.cache.enabled配置
        if (!activeMQSettings.isCacheEnabled()) {
            return factory;
        } else {
            CachingConnectionFactory cachingFactory = new CachingConnectionFactory(factory);
            cachingFactory.setSessionCacheSize(1); // 按需调整缓存大小
            return cachingFactory;
        }
    }

    // 创建JmsTemplate,支持主题模式
    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
        JmsTemplate template = new JmsTemplate(connectionFactory);
        template.setPubSubDomain(true); // 必须设置为true才能监听主题(队列用false)
        return template;
    }

    // 配置主题监听容器,自动监听指定主题
    @Bean
    public DefaultMessageListenerContainer topicListenerContainer(ConnectionFactory connectionFactory,
                                                                 TopicMessageListener messageListener) {
        DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setDestinationName("your-target-topic"); // 替换成你要监听的主题名
        container.setMessageListener(messageListener);
        container.setPubSubDomain(true); // 主题模式必须开启
        return container;
    }
}

4. 编写消息监听器

创建一个简单的监听器类,处理收到的主题消息:

import org.springframework.stereotype.Component;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@Component
public class TopicMessageListener implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            if (message instanceof TextMessage) {
                String content = ((TextMessage) message).getText();
                System.out.println("✅ 收到主题消息:" + content);
                // 这里写你的业务逻辑
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. 在Dropwizard应用中集成Spring

最后,在你的Dropwizard主类里启动Spring上下文,并把配置传递进去:

import io.dropwizard.Application;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class MyDropwizardApp extends Application<AppConfig> {

    private ConfigurableApplicationContext springContext;

    @Override
    public void initialize(Bootstrap<AppConfig> bootstrap) {
        // 初始化Dropwizard的其他组件(比如bundle)
    }

    @Override
    public void run(AppConfig config, Environment env) throws Exception {
        // 启动Spring上下文,把Dropwizard的配置传递给Spring
        springContext = new SpringApplicationBuilder(MyDropwizardApp.class)
                .run();
        
        // 如果需要把Spring的Bean注册到Dropwizard的Jersey环境(比如REST接口),可以这么做:
        // env.jersey().register(springContext.getBean(YourRestResource.class));
    }

    public static void main(String[] args) throws Exception {
        new MyDropwizardApp().run(args);
    }
}

关键注意点

  • 不要用Spring Boot的spring.activemq.*配置格式,Dropwizard只认自己配置类绑定的节点结构。
  • 主题监听必须设置setPubSubDomain(true),否则会被当成队列处理,收不到主题消息。
  • 如果你用的是dropwizard-spring这类集成bundle,配置传递会更简单,但上面的写法是最通用的方式,改动最小。

内容的提问来源于stack exchange,提问作者maverickabhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 20:37:39