如何指示spring实例化消息监听器容器?

时间:2015-11-20 20:20:23

标签: spring jms activemq spring-jms

我正在使用Spring 4.2.3和Java 1.7

我有一个单元测试

@ContextConfiguration(classes = TestConfiguration.class)
public class TestJmsListener extends AbstractTestNGSpringContextTests {

    @Autowired
    private JmsMessagingTemplate jmsTemplate;

    @Autowired
    @Qualifier("destination")
    private Destination destination;

    @Test
    public void test() {
        assert(jmsTemplate.convertSendAndReceive(destination, "test", Boolean.class));
    }

}

测试调用TestConfiguration类,但实际上只是扩展了以下配置。在TestConfiguration中,我只是覆盖connectionFactory,以便它实例化一个嵌入的activemq代理。

@Configuration
@EnableJms
@ComponentScan("messaging")
@PropertySource(value = "classpath:messaging.properties")
public class CommonMessagingConfiguration {

    // bunch of beans, connection factories, destinations, etc

    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory());
        factory.setConcurrency("10");
        return factory;
    }

}

测试执行,在日志中我可以看到为我的" test"创建了一个队列。信息。消息在队列中挂起,但队列中没有消费者。这是我的听众实现:

@Component
public class JmsExampleListener {

    @JmsListener(containerFactory = "jmsListenerContainerFactory",
            destination = "${messaging.destinations.example}")
    public boolean listen(String message) {
        return message != null;
    }
}

当我将调试器附加到DefaultJmsListenerContainerFactory#createContainerInstance()时,我注意到它被击中了。但是,当我将一个附加到JmsListenerAnnotationBeanPostProcessor#postProcessAfterInitialization时,它会触及该断点,我可以看到弹簧正在检测我的组件。 Spring实例化它并将该实例注册到它的内部注册器(正如我所料)。

似乎问题是永远不会为已注册的端点创建容器。我试过跟Spring example,但他们没有提供任何见解。

我注意到的一件事是,监听器后处理器有一个内部注册器,其内部属性startImmediately是假的。它似乎扩展了InitializingBean,因此,将start属性设置为true,我认为这将开始启动容器......但是,这不会发生。事实上,如果我在afterPropertiesSet上设置一个断点,它就永远不会被调用。我假设因为后处理器中的实例不是Spring托管bean。

有没有人尝试过类似于我正在做的事情并遇到同样的问题?

更新

经过进一步调查后,似乎@EnableJms实例化的JmsListenerAnnotationBeanPostProcessor在配置容器后调用了afterSingletonsInstantiated MessageListenerContainer 。上述方法中的逻辑是负责为所有已注册的端点构造afterSingletonsInstantiated的逻辑。为什么不调用div { position:relative; border-radius:1em; background: linear-gradient(to top, transparent 30%, white 30%, white 70%, transparent 70%),linear-gradient(to left, transparent 30%, white 30%, white 70%, transparent 70%); } div:before { content:''; position:absolute; border-radius:1em; z-index:-1;/* draw it under */ top:0; left:0; right:0; bottom:0; box-shadow: inset 0 0 0 1px, /* hide it with bg */ 0 0 0 1px lightgray /* see that one */; } /* draw circles */ h2:before { content:''; position:absolute; top:-4px; left:-4px; z-index:1; height:8px; width:8px; border-radius:100%; box-shadow: 0 7vw 0 0 white, 0 7vw 0 1px , 0 3vw 0 0 white , 0 3vw 0 1px , 50vw 7vw 0 0 white, 50vw 7vw 0 1px , 50vw 3vw 0 0 white, 50vw 3vw 0 1px , 15vw 0 0 0 white, 15vw 0 0 1px, 35vw 0 0 0 white, 35vw 0 0 1px, 15vw 10vw 0 0 white, 15vw 10vw 0 1px, 35vw 10vw 0 0 white, 35vw 10vw 0 1px ; } /* DEMO purpose */ html { display:flex; min-height:100%; } body { margin:auto; } div:after { content:''; display:block; padding-top:10vw; } div { display:flex; align-items:center; justify-content:center; width:50vw; }?应用程序上下文是否应该自动调用它?

1 个答案:

答案 0 :(得分:2)

事实证明,我有一个项目依赖项导致spring-context源版本为4.0.9。在解决冲突并有效地从4.2.3加载AbstractApplicationContext后,组件开始工作。