我的Spring Integration项目没有关闭。在我的IDE(IntelliJ)中,STOP按钮是不够的。我必须使用kill(skull)按钮来关闭应用程序。
我认为这与运行尚未完成的线程有关。
所以,我禁用了所有MessageSource
bean(Jms入站适配器)。
事实上,这很有效:应用程序正常关闭。
我尝试调试进程,希望调试器Threads视图中有剩余的Thread。但是没有留下任何东西(按下'停止',但在按下' kill')之前。
这是点击' stop'后的日志(与jms消息源bean ):
2017-08-11 11:51:49,089 INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter: Unregistering JMX-exposed beans on shutdown
2017-08-11 11:51:49,090 INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter: Unregistering JMX-exposed beans
2017-08-11 11:51:49,091 INFO org.springframework.jmx.export.annotation.AnnotationMBeanExporter: Unregistering JMX-exposed beans on shutdown
2017-08-11 11:51:49,091 INFO org.springframework.jmx.export.annotation.AnnotationMBeanExporter: Unregistering JMX-exposed beans
2017-08-11 11:51:49,092 INFO org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler: Shutting down ExecutorService 'taskScheduler'
其次是' kill'我明白了:
Disconnected from server
点击'停止'后的日志(没有jms消息源bean ):
2017-08-11 11:48:27,432 INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter: Unregistering JMX-exposed beans on shutdown
2017-08-11 11:48:27,432 INFO org.springframework.boot.actuate.endpoint.jmx.EndpointMBeanExporter: Unregistering JMX-exposed beans
11-Aug-2017 11:48:27.463 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [myapp] registered the JDBC driver [org.postgresql.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
2017-08-11 11:48:27,432 INFO org.springframework.jmx.export.annotation.AnnotationMBeanExporter: Unregistering JMX-exposed beans on shutdown
11-Aug-2017 11:48:27.463 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [myapp] registered the JDBC driver [oracle.jdbc.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
2017-08-11 11:48:27,432 INFO org.springframework.jmx.export.annotation.AnnotationMBeanExporter: Unregistering JMX-exposed beans
11-Aug-2017 11:48:27.463 SEVERE [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [myapp] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@59d61fb3]) and a value of type [java.lang.Class] (value [class oracle.sql.AnyDataFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2017-08-11 11:48:27,447 INFO org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler: Shutting down ExecutorService 'taskScheduler'
11-Aug-2017 11:48:27.463 SEVERE [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [myapp] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@30aaad16]) and a value of type [java.lang.Class] (value [class oracle.sql.TypeDescriptorFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2017-08-11 11:48:27,447 INFO org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean: Closing JPA EntityManagerFactory for persistence unit 'default'
11-Aug-2017 11:48:27.463 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"]
11-Aug-2017 11:48:27.641 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
11-Aug-2017 11:48:27.642 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-8080"]
11-Aug-2017 11:48:27.650 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]
Disconnected from server
我认为这是由于这些JMS适配器上的预定消息轮询所致。我必须手动杀死它们吗?
顺便说一句:我试过等待15分钟,但这没有效果。编辑 - 根据@ArtemBilan的要求,我使用了更多代码。
private String jmsOutbound = "QUEUE_NAME_IN_ORACLE";
@Bean
public DataSource oracleDataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setURL(this.dataSourceURL);
dataSource.setPassword(this.dataSourcePassword);
dataSource.setUser(this.dataSourceUser);
Properties connectionProperties = new Properties();
connectionProperties.setProperty("MinLimit", this.minLimit);
connectionProperties.setProperty("MaxLimit", this.maxLimit);
connectionProperties.setProperty("ValidateConnection", "true");
dataSource.setConnectionCachingEnabled(true);
dataSource.setConnectionCacheProperties(connectionProperties);
return dataSource;
}
@Bean
public ConnectionFactory oracleConnectionFactory() throws Exception {
return AQjmsFactory.getQueueConnectionFactory(oracleDataSource());
}
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.BYTES);
converter.setTypeIdPropertyName("_type");
return converter;
}
@Bean
@InboundChannelAdapter(value = "loaderResponseChannel")
public MessageSource loaderResponseSource() throws Exception {
return Jms
.inboundAdapter(oracleConnectionFactory())
.configureJmsTemplate(
t -> t.deliveryPersistent(true)
.jmsMessageConverter(jacksonJmsMessageConverter())
).destination(jmsInbound).get();
}
// and to be complete also the outbound.
@Bean
@ServiceActivator(inputChannel = "loaderRequestChannel")
public JmsSendingMessageHandler loaderRequestHandler() throws Exception {
return Jms
.outboundAdapter(oracleConnectionFactory())
.configureJmsTemplate(
t -> t.jmsMessageConverter(jacksonJmsMessageConverter()))
.destination(jmsOutbound)
.get();
}
我希望这会有所帮助。