2017-04-03 84 views
2

我遇到了一个问题,试图正常关闭Tomcat(8)永远不会结束,因为看起来是DefaultMessageListenerContainer被无限期阻止(或循环)。Tomcat挂起Spring集成Java DSL关闭

我一直在搜索解决方案,但我发现的任何类似的东西都没有奏效。这包括(但不限于):

  • 使用configureListenerContainer()设置容器
  • 使用Messages.queue()代替Messages.direct()
  • 结束语在CachingConnectionFactory

一个简单的ActiveMQConnectionFactory的了taskExecutor Servlet 3.0示例:

compile 'org.springframework.integration:spring-integration-core:4.3.6.RELEASE' 
compile 'org.springframework.integration:spring-integration-jms:4.3.6.RELEASE' 
compile 'org.springframework.integration:spring-integration-java-dsl:1.2.1.RELEASE' 

初始化器:

public class ExampleWebApp implements WebApplicationInitializer { 
    @Override 
    public void onStartup(final ServletContext servletContext) throws ServletException { 
     final AnnotationConfigWebApplicationContext springContext = new AnnotationConfigWebApplicationContext(); 
     springContext.register(ExampleConfig.class); 

     servletContext.addListener(new ContextLoaderListener(springContext)); 

     final ServletRegistration.Dynamic registration = servletContext.addServlet("example", new HttpRequestHandlerServlet()); 
     registration.setLoadOnStartup(1); 
     registration.addMapping("/status"); 
    } 
} 

配置:

@Configuration 
@EnableIntegration 
public class ExampleConfig { 
    @Bean 
    public ConnectionFactory connectionFactory() { 
     final ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory(); 
     mqConnectionFactory.setBrokerURL("tcp://host:port"); 
     mqConnectionFactory.setUserName("----"); 
     mqConnectionFactory.setPassword("----"); 

     return mqConnectionFactory; 
    } 

    @Bean 
    public Queue testQueue() { 
     return new ActiveMQQueue("test.queue"); 
    } 

    @Bean 
    public MessageChannel testReceiveChannel() { 
     return MessageChannels.direct().get(); 
    } 

    @Bean 
    public IntegrationFlow pushMessageInboundFlow() { 
     return IntegrationFlows 
       .from(Jms.messageDrivenChannelAdapter(connectionFactory()) 
         .destination(testQueue())) 
       .log() 
       .transform(new JsonToObjectTransformer(TestMessageObject.class)) 
       .channel(testReceiveChannel()) 
       .get(); 
    } 

    /** Example message object */ 
    public static class TestMessageObject { 
     private String text; 

     public String getText() { 
      return text; 
     } 

     public void setText(final String text) { 
      this.text = text; 
     } 
    } 
} 

如果我试图通过catalina.sh脚本停止这种(例如,按下 “停止” 的IntelliJ中”,它永远不会完成现有的。到目前为止,我已经能够得到关机到结束的唯一方式是通过一个小的辅助类“手工”毁在关机JmsMessageAdapters,:

public class JmsMessageListenerContainerLifecycleManager { 
    private static final Logger LOG = LoggerFactory.getLogger(JmsMessageListenerContainerLifecycleManager.class); 

    @Autowired 
    private List<IntegrationFlow> mIntegrationFlows; 

    @PreDestroy 
    public void shutdownJmsAdapters() throws Exception { 
     LOG.info("Checking {} integration flows for JMS message adapters", mIntegrationFlows.size()); 

     for (IntegrationFlow flow : mIntegrationFlows) { 
      if (flow instanceof StandardIntegrationFlow) { 
       final StandardIntegrationFlow standardFlow = (StandardIntegrationFlow) flow; 

       for (Object component : standardFlow.getIntegrationComponents()) { 
        if (component instanceof JmsMessageDrivenChannelAdapter) { 
         final JmsMessageDrivenChannelAdapter adapter = (JmsMessageDrivenChannelAdapter) component; 

         LOG.info("Destroying JMS adapter {}", adapter.getComponentName()); 
         adapter.destroy(); 
        } 
       } 
      } 
     } 
    } 
} 

虽然这样的作品,它肯定感觉错了解。

以前我使用的是spring-integration的XML配置,我没有这个问题。我错过了什么?

回答

1

呃!这绝对是一个错误。看起来像你正确地解决它。

虽然考虑销毁任何DisposableBean那里。

我正在给Spring Integration Java DSL添加修订。我们将在Spring Integration 4.3.9之后发布下一个1.2.2

Spring Integration 5.0将在明天发布M3版本。