You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot集成ActiveMQ:自定义连接工厂与队列查找咨询

嘿,刚接触Spring Boot集成ActiveMQ的话,这个需求其实不难实现,我帮你一步步梳理清楚~

实现步骤详解

1. 先禁用Spring Boot的ActiveMQ自动配置

Spring Boot默认会帮你自动创建一个ActiveMQ的ConnectionFactory,但咱们要自定义,所以第一步先把这个自动配置关掉。只需要在你的启动类上加上排除配置就行:

@SpringBootApplication(exclude = ActiveMQAutoConfiguration.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. 自定义你自己的ConnectionFactory

接下来咱们手动定义ConnectionFactory的Bean,完全按照你的需求配置:

@Configuration
public class ActiveMQConfig {

    // 可以把配置项放到application.properties里,用@Value读取
    @Value("${activemq.broker-url}")
    private String brokerUrl;

    @Value("${activemq.username}")
    private String username;

    @Value("${activemq.password}")
    private String password;

    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(brokerUrl); // 比如tcp://localhost:61616
        connectionFactory.setUserName(username);
        connectionFactory.setPassword(password);
        // 还可以加一些额外配置,比如信任包、超时时间之类的,按需添加
        return connectionFactory;
    }

    // 要是想用连接池优化性能,就用PooledConnectionFactory包装一下
    @Bean
    public PooledConnectionFactory pooledConnectionFactory(ConnectionFactory connectionFactory) {
        PooledConnectionFactory pooledConnFactory = new PooledConnectionFactory();
        pooledConnFactory.setConnectionFactory(connectionFactory);
        pooledConnFactory.setMaxConnections(10); // 连接数根据你的业务调整
        return pooledConnFactory;
    }
}

3. 用预定义队列,拒绝dynamicqueues

这里分两种场景,选适合你的就行:

场景一:直接用已存在的队列(不用JNDI)

如果你的队列已经在ActiveMQ服务器上创建好了(比如通过管理控制台手动建的),直接在配置类里声明这个队列的Bean就行,这样就不会触发动态队列的创建:

@Bean
public Queue myPredefinedQueue() {
    // 这里的名称必须和ActiveMQ上已存在的队列名完全一致!
    return new ActiveMQQueue("my-existing-queue");
}

之后在生产者或者消费者里直接注入这个Queue使用:

@Component
public class MessageProducer {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    private Queue myPredefinedQueue;

    public void sendMessage(String content) {
        jmsTemplate.convertAndSend(myPredefinedQueue, content);
    }
}

场景二:通过JNDI查找队列(需要jndi.properties)

如果你的队列和ConnectionFactory是通过JNDI注册的,那确实需要创建jndi.properties文件,放在src/main/resources目录下,内容示例:

java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:61616
# 有认证的话加上用户名密码
java.naming.security.principal=admin
java.naming.security.credentials=admin
# 把已存在的队列绑定到JNDI名称上
queue.my-predefined-queue=my-existing-queue

然后在配置类里通过JNDI来获取ConnectionFactory和队列:

@Configuration
public class JndiActiveMQConfig {

    @Bean
    public JndiTemplate jndiTemplate() throws IOException {
        JndiTemplate jndiTemplate = new JndiTemplate();
        Properties props = new Properties();
        props.load(Objects.requireNonNull(getClass().getResourceAsStream("/jndi.properties")));
        jndiTemplate.setEnvironment(props);
        return jndiTemplate;
    }

    @Bean
    public ConnectionFactory connectionFactory(JndiTemplate jndiTemplate) throws NamingException {
        return (ConnectionFactory) jndiTemplate.lookup("ConnectionFactory");
    }

    @Bean
    public Queue predefinedQueue(JndiTemplate jndiTemplate) throws NamingException {
        return (Queue) jndiTemplate.lookup("my-predefined-queue");
    }
}

额外提醒

  • 如果你不需要JNDI的话,完全不用搞jndi.properties,场景一的配置就足够满足需求了。
  • 要是怕不小心创建动态队列,可以去ActiveMQ的activemq.xml配置文件里修改规则,比如在policyEntry里设置createDestinationConnectorfalse,或者限制动态队列的前缀。

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

火山引擎 最新活动