【无标题】

1、是springboot 整合 activeMq
查了网上各种出现此错误的解决办法,都是手动创建connectionFactory并创建JmsTemplate相关Bean对象。但是这种方式治标不治本。既然spring boot官方有整合ActiveMQ的相关方法,不可能会要求用户自己手动去创建相关的Bean对象的。此处个人进行了相关的分析并给出了对应解决办法:
通过查看日志(以上截取的有这段日志):

JmsAutoConfiguration:
Did not match:
- @ConditionalOnBean (types: javax.jms.ConnectionFactory; SearchStrategy: all) did not find any beans of type javax.jms.ConnectionFactory (OnBeanCondition)
说明spring 容器中并未有ConnectionFactory相关的bean对象。在往上翻日志会有如下几段日志:

ActiveMQConnectionFactoryConfiguration.PooledConnectionFactoryConfiguration:
Did not match:
- @ConditionalOnClass did not find required class ‘org.messaginghub.pooled.jms.JmsPoolConnectionFactory’ (OnClassCondition)
ActiveMQConnectionFactoryConfiguration.SimpleConnectionFactoryConfiguration:
Did not match:
- @ConditionalOnProperty (spring.activemq.pool.enabled=false) found different value in property ‘enabled’ (OnPropertyCondition)
Matched:
- @ConditionalOnClass found required class ‘org.springframework.jms.connection.CachingConnectionFactory’ (OnClassCondition)
spring boot 要使用PooledConnectionFactoryConfiguration静态内部类需要类路径下存在org.messaginghub.pooled.jms.JmsPoolConnectionFactory类。
我这里截取了PooledConnectionFactoryConfiguration相关的源码:

@Configuration
@ConditionalOnClass({ JmsPoolConnectionFactory.class, PooledObject.class })
static class PooledConnectionFactoryConfiguration {

    @Bean(destroyMethod = "stop")
    @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
    public JmsPoolConnectionFactory pooledJmsConnectionFactory(
            ActiveMQProperties properties,
            ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory(
                properties,
                factoryCustomizers.orderedStream().collect(Collectors.toList()))
                        .createConnectionFactory(ActiveMQConnectionFactory.class);
        return new JmsPoolConnectionFactoryFactory(properties.getPool())
                .createPooledConnectionFactory(connectionFactory);
    }
}

PooledConnectionFactoryConfiguration这个静态内部类中pooledJmsConnectionFactory方法上标注了@Bean,说明此方法返回的对象会被加入到spring容器中。而返回的JmsPoolConnectionFactory对象元类实现了ConnectionFactory接口。所以此静态内部类便是出现问题的源头。
由于spring boot自动配置该内部类的条件是类路径下必须存在JmsPoolConnectionFactory和PooledObject两个类。
查看了依赖包中并未找到JmsPoolConnectionFactory该类,从日志信息上看到该类应该存放于org.messaginghub.pooled.jms包下的。但是我们依赖中并未引入相关的依赖包。从maven中央仓库中查询了该包的前缀org.messaginghub发现该依赖是在PooledJMS Library下的。然后尝试引入该maven依赖并去掉原来的ActiveMQ Pool依赖:

org.messaginghub pooled-jms

重新启动spring boot 应用后,问题解决了。
spring boot 2.1.*中引入了CachingConnectionFactory,所以在application.properties可以使用spring.jms.cache.**相关的配置。
查看spring boot 2.1.*和spring boot 2.0.*整合ActiveMQ时需要的重要类ActiveMQConnectionFactoryConfiguration源码:

//spring boot 2.1.*版本的源码如下
@Configuration
@ConditionalOnMissingBean(ConnectionFactory.class)
class ActiveMQConnectionFactoryConfiguration {

@Configuration
@ConditionalOnClass(CachingConnectionFactory.class)
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
static class SimpleConnectionFactoryConfiguration {

    private final JmsProperties jmsProperties;

    private final ActiveMQProperties properties;

    private final List<ActiveMQConnectionFactoryCustomizer> connectionFactoryCustomizers;

    SimpleConnectionFactoryConfiguration(JmsProperties jmsProperties,
            ActiveMQProperties properties,
            ObjectProvider<ActiveMQConnectionFactoryCustomizer> connectionFactoryCustomizers) {
        this.jmsProperties = jmsProperties;
        this.properties = properties;
        this.connectionFactoryCustomizers = connectionFactoryCustomizers
                .orderedStream().collect(Collectors.toList());
    }

    @Bean
    @ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "true", matchIfMissing = true)
    public CachingConnectionFactory cachingJmsConnectionFactory() {
        JmsProperties.Cache cacheProperties = this.jmsProperties.getCache();
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
                createConnectionFactory());
        connectionFactory.setCacheConsumers(cacheProperties.isConsumers());
        connectionFactory.setCacheProducers(cacheProperties.isProducers());
        connectionFactory.setSessionCacheSize(cacheProperties.getSessionCacheSize());
        return connectionFactory;
    }

    @Bean
    @ConditionalOnProperty(prefix = "spring.jms.cache", name = "enabled", havingValue = "false")
    public ActiveMQConnectionFactory jmsConnectionFactory() {
        return createConnectionFactory();
    }

    private ActiveMQConnectionFactory createConnectionFactory() {
        return new ActiveMQConnectionFactoryFactory(this.properties,
                this.connectionFactoryCustomizers)
                        .createConnectionFactory(ActiveMQConnectionFactory.class);
    }

}

@Configuration
@ConditionalOnClass({ JmsPoolConnectionFactory.class, PooledObject.class })
static class PooledConnectionFactoryConfiguration {

    @Bean(destroyMethod = "stop")
    @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
    public JmsPoolConnectionFactory pooledJmsConnectionFactory(
            ActiveMQProperties properties,
            ObjectProvider<ActiveMQConnectionFactoryCustomizer> factoryCustomizers) {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactoryFactory(
                properties,
                factoryCustomizers.orderedStream().collect(Collectors.toList()))
                        .createConnectionFactory(ActiveMQConnectionFactory.class);
        return new JmsPoolConnectionFactoryFactory(properties.getPool())
                .createPooledConnectionFactory(connectionFactory);
    }

}

}

//spring 2.0.*版本的源码如下
@Configuration
@ConditionalOnMissingBean(ConnectionFactory.class)
class ActiveMQConnectionFactoryConfiguration {

@Bean
@ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
public ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
        ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
    return new ActiveMQConnectionFactoryFactory(properties,
            factoryCustomizers.getIfAvailable())
                    .createConnectionFactory(ActiveMQConnectionFactory.class);
}

@Configuration
@ConditionalOnClass(PooledConnectionFactory.class)
static class PooledConnectionFactoryConfiguration {

    @Bean(destroyMethod = "stop")
    @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
    public PooledConnectionFactory pooledJmsConnectionFactory(
            ActiveMQProperties properties,
            ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
        PooledConnectionFactory pooledConnectionFactory = new PooledConnectionFactory(
                new ActiveMQConnectionFactoryFactory(properties,
                        factoryCustomizers.getIfAvailable()).createConnectionFactory(
                                ActiveMQConnectionFactory.class));
        ActiveMQProperties.Pool pool = properties.getPool();
        pooledConnectionFactory.setBlockIfSessionPoolIsFull(pool.isBlockIfFull());
        if (pool.getBlockIfFullTimeout() != null) {
            pooledConnectionFactory.setBlockIfSessionPoolIsFullTimeout(
                    pool.getBlockIfFullTimeout().toMillis());
        }
        pooledConnectionFactory
                .setCreateConnectionOnStartup(pool.isCreateConnectionOnStartup());
        if (pool.getExpiryTimeout() != null) {
            pooledConnectionFactory
                    .setExpiryTimeout(pool.getExpiryTimeout().toMillis());
        }
        if (pool.getIdleTimeout() != null) {
            pooledConnectionFactory
                    .setIdleTimeout((int) pool.getIdleTimeout().toMillis());
        }
        pooledConnectionFactory.setMaxConnections(pool.getMaxConnections());
        pooledConnectionFactory.setMaximumActiveSessionPerConnection(
                pool.getMaximumActiveSessionPerConnection());
        pooledConnectionFactory
                .setReconnectOnException(pool.isReconnectOnException());
        if (pool.getTimeBetweenExpirationCheck() != null) {
            pooledConnectionFactory.setTimeBetweenExpirationCheckMillis(
                    pool.getTimeBetweenExpirationCheck().toMillis());
        }
        pooledConnectionFactory
                .setUseAnonymousProducers(pool.isUseAnonymousProducers());
        return pooledConnectionFactory;
    }

}

}
springboot 2.1.*需要使用JmsPoolConnectionFactory和PooledObject,而2.0.*则是直接使用PooledConnectionFactory。2.1.*增加了JMS缓存连接工厂,默认采用的连接池不再是activeMQ的连接池,而是采用了PooledJMS Library。当配置spring.activemq.pool.enabled为true时使用的是JmsPoolConnectionFactoryProperties而不是Pool。相比2.0.*代码有较大的改动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值