将RedeliveryPolicy注入Spring引导ActiveMQ

时间:2017-07-28 10:56:05

标签: spring spring-boot configuration jms activemq

我正在spring-boot-starter-activemq使用PoolFactory。一切都很好,并且很容易通过application.yaml配置,但我找不到正确的方法来注入我的自定义RedeliveryPolicy。所以问题是我该怎么做?

2 个答案:

答案 0 :(得分:5)

可以在连接工厂上设置重新传递策略。由于弹簧引导自动配置连接工厂,您可以添加一个方法来设置它。

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.RedeliveryPolicy;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Foo
{
    @Bean
    public InitializingBean connectionFactory(ActiveMQConnectionFactory connectionFactory)
    {
        return () ->
        {
            RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
            // configure redelivery policy
            connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
        };
    }
}

<强>更新

如一个回复中所述,如果未设置以下配置spring.activemq.pool.enabled = true,则上述解决方案效果很好。

使用池连接工厂时,Spring Boot会自动配置org.apache.activemq.pool.PooledConnectionFactory而不是org.apache.activemq.ActiveMQConnectionFactory。此配置在此处发生:org.springframework.boot.autoconfigure.jms.activemq.ActiveMQConnectionFactoryConfiguration.PooledConnectionFactoryConfiguration#pooledJmsConnectionFactory在以下行中:

PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(new ActiveMQConnectionFactoryFactory(properties,factoryCustomizers.getIfAvailable()).createConnectionFactory(ActiveMQConnectionFactory.class));

为了完成这项工作,您有两种选择:

  1. 在注入bean ActiveMQConnectionFactory时使用PooledConnectionFactoryjavax.jms.ConnectionFactory的公共父级,并使用instance-of和cast来设置重新传递策略。

        @Bean
        public InitializingBean connectionFactory(ConnectionFactory connectionFactory) {
    
            if (connectionFactory instanceof ActiveMQConnectionFactory) {
                return configureRedeliveryPolicy((ActiveMQConnectionFactory) connectionFactory);
    
            } else if (connectionFactory instanceof PooledConnectionFactory) {
                final PooledConnectionFactory pooledConnectionFactory = (PooledConnectionFactory) connectionFactory;
                if (pooledConnectionFactory.getConnectionFactory() instanceof ActiveMQConnectionFactory) {
                    return configureRedeliveryPolicy((ActiveMQConnectionFactory) pooledConnectionFactory.getConnectionFactory());
                }
            }
            // ...
        }
    
  2. 为每种bean类型提供两种不同的自定义初始化方案,基本上与1相同,但您正在利用ConditionalOnBean而不是检查connectionFactory类类型。

    @Configuration
    public class Foo {
        @Bean
        @ConditionalOnBean(ActiveMQConnectionFactory.class)
        public InitializingBean connectionFactory(ActiveMQConnectionFactory connectionFactory) {
            return configureRedeliveryPolicy(connectionFactory);
        }
    
        @Bean
        @ConditionalOnBean(PooledConnectionFactory.class)
        public InitializingBean pooledConnectionFactory(PooledConnectionFactory connectionFactory) {
            if (connectionFactory.getConnectionFactory() instanceof ActiveMQConnectionFactory) {
                return configureRedeliveryPolicy((ActiveMQConnectionFactory) connectionFactory.getConnectionFactory());
            } else return () -> {
                // do something else
            };
        }
    
        private InitializingBean configureRedeliveryPolicy(ActiveMQConnectionFactory connectionFactory) {
            return () ->
            {
                RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
                // configure redelivery policy
                connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
            };
        }
    }
    

答案 1 :(得分:1)

我尝试了@Iulian Rosca的答案,但不适用于最新版本的spring-boot-starter-activemq(我使用的是2.2.0.RELEASE版本)。

Spring为ConnectionFactory提供了许多其他实现类,例如CachingConnectionFactoryJmsPooledConnectionFactory,...,并且它们彼此之间没有继承。因此,上述解决方案需要使用多种类类型进行重构。

我发现Spring提供了一个功能接口ActiveMQConnectionFactoryCustomizer,无论创建哪个类,该接口都会在创建ActiveMQ Connection Factory时注入。它将自定义连接工厂类,您可以设置任何属性,而不仅仅是重新交付策略。

这是我的示例代码:

@Configuration
public class RedeliveryCofiguration {

    @Bean
    public ActiveMQConnectionFactoryCustomizer configureRedeliveryPolicy() {
        return connectionFactory ->
        {
            RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
            // configure redelivery policy
            connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
        };
    }
}