Java利用ShutDownHook關(guān)閉系統(tǒng)資源
Java關(guān)閉鉤子
在Java程序中能夠通過(guò)加入關(guān)閉鉤子,實(shí)如今程序退出時(shí)關(guān)閉資源的功能。
使用Runtime.addShutdownHook(Thread hook)向JVM加入關(guān)閉鉤子
public void addShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
ApplicationShutdownHooks.add(hook);
}
ShutdownHook(Thread hook)方法,能夠注冊(cè)一個(gè)JVM關(guān)閉的鉤子,這個(gè)鉤子能夠在以下幾種場(chǎng)景被調(diào)用:
1)程序正常退出
2)使用System.exit()
3)終端使用Ctrl+C觸發(fā)的中斷
4)系統(tǒng)關(guān)閉
5)使用Kill pid命令干掉進(jìn)程
在Eclipse中使用關(guān)閉鉤子
在Eclipse中直接點(diǎn)擊Terminate關(guān)閉程序時(shí)不會(huì)觸發(fā)關(guān)閉鉤子的。
在Linux下使用kill -9也是不會(huì)觸發(fā)鉤子的
假設(shè)想在Eclipse中實(shí)現(xiàn)關(guān)閉鉤子的功能,須要另起一個(gè)線(xiàn)程監(jiān)聽(tīng)控制臺(tái),在控制臺(tái)輸入Enter時(shí)關(guān)閉系統(tǒng)
/**
* <p>類(lèi)描寫(xiě)敘述: 輸入Enter鍵關(guān)閉系統(tǒng) </p>
* <p>創(chuàng)建人:王成委 </p>
* <p>創(chuàng)建時(shí)間:2015年6月8日 下午5:23:31 </p>
*/
public class ExitThread extends Thread {
private Log logger = LogFactory.getLog(getClass());
public void run() {
logger.info("press ENTER to call System.exit(0) ");
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}
}
Spring中關(guān)閉資源的配置
在使用Spring時(shí)。能夠在Bean中配置destroy-method來(lái)實(shí)現(xiàn)系統(tǒng)關(guān)閉時(shí)對(duì)Bean的一些處理。
<bean id="simpleHandler" class="com.tiamaes.gjds.socket.server.SimpleHanlder" destroy-method="destroy">
<property name="annotationSocketServiceFactory" ref="annotationSocketServiceFactory" />
</bean>
//此方法須要聲明void。而且沒(méi)有不論什么參數(shù)
public void destroy(){
logger.info("Stop socket handler.");
}
Java+Spring實(shí)如今程序退出時(shí)關(guān)閉Spring
/**
* <p>類(lèi)描寫(xiě)敘述: 系統(tǒng)關(guān)閉鉤子,用于關(guān)閉Spring資源 </p>
* <p>創(chuàng)建人:王成委 </p>
* <p>創(chuàng)建時(shí)間:2015年6月8日 下午5:06:46 </p>
*/
public class ShutDownHook extends Thread {
private Log logger = LogFactory.getLog(getClass());
private ConfigurableApplicationContext applicationContext;
public ShutDownHook(ConfigurableApplicationContext applicationContext ){
super();
this.applicationContext = applicationContext;
}
@Override
public void run() {
logger.info("Start clean the login info.");
//在系統(tǒng)關(guān)閉時(shí),清理全部用戶(hù)的登錄狀態(tài)
TbDxpUserLoginStatusRepository repository = applicationContext.getBean(TbDxpUserLoginStatusRepository.class);
repository.deleteAll();
applicationContext.close();
logger.info("Socket server shutdown");
}
}
在ShutdownHook實(shí)例化時(shí)須要傳入Spring上下文,在系統(tǒng)關(guān)閉時(shí)調(diào)用ApplicationContext的Close方法。
public static void main(String[] args) {
ClassPathXmlApplicationContext ct =
new ClassPathXmlApplicationContext("applicationContext.xml");
Runtime.getRuntime().addShutdownHook(new ShutDownHook(ct));
//在正式部署時(shí)不須要以下的代碼,這段代碼僅供調(diào)試時(shí)使用
Thread thread = new ExitThread();
thread.start();
}
終于效果例如以下
2015-06-09 09:43:51,233 INFO ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2e52cdcc: startup date [Tue Jun 09 09:43:51 CST 2015]; root of context hierarchy
2015-06-09 09:43:52,263 INFO XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
2015-06-09 09:43:55,559 INFO XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext-service.xml]
2015-06-09 09:43:55,724 INFO XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext-db.xml]
2015-06-09 09:44:01,358 INFO PropertyPlaceholderConfigurer - Loading properties file from class path resource [jdbc.properties]
2015-06-09 09:44:02,687 INFO MLog - MLog clients using slf4j logging.
2015-06-09 09:44:06,563 INFO C3P0Registry - Initializing c3p0-0.9.5-pre9 [built 08-October-2014 03:06:08 -0700; debug? true; trace: 10]
2015-06-09 09:44:08,930 INFO LocalContainerEntityManagerFactoryBean - Building JPA container EntityManagerFactory for persistence unit 'Oracle'
2015-06-09 09:44:09,251 INFO LogHelper - HHH000204: Processing PersistenceUnitInfo [
name: Oracle
...]
2015-06-09 09:44:13,400 INFO Version - HHH000412: Hibernate Core {4.3.7.Final}
2015-06-09 09:44:13,404 INFO Environment - HHH000206: hibernate.properties not found
2015-06-09 09:44:13,439 INFO Environment - HHH000021: Bytecode provider name : javassist
2015-06-09 09:44:15,016 INFO Version - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2015-06-09 09:44:15,660 INFO Dialect - HHH000400: Using dialect: org.hibernate.dialect.Oracle10gDialect
2015-06-09 09:44:15,739 INFO LobCreatorBuilder - HHH000422: Disabling contextual LOB creation as connection was null
2015-06-09 09:44:16,056 INFO ASTQueryTranslatorFactory - HHH000397: Using ASTQueryTranslatorFactory
2015-06-09 09:44:21,032 INFO EhCacheManagerFactoryBean - Initializing EhCache CacheManager
2015-06-09 09:44:21,977 INFO ExitThread - press ENTER to call System.exit(0)
2015-06-09 09:54:23,694 INFO ShutDownHook - Start clean the login info.
2015-06-09 09:54:23,787 INFO AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 0, acquireRetryDelay -> 1000, autoCommitOnClose -> true, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 5000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, contextClassLoaderSource -> caller, dataSourceName -> 1hge7dt991ndh1jygiycad|7402fff0, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> oracle.jdbc.OracleDriver, extensions -> {}, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, forceUseNamedDriverClass -> false, identityToken -> 1hge7dt991ndh1jygiycad|7402fff0, idleConnectionTestPeriod -> 0, initialPoolSize -> 5, jdbcUrl -> jdbc:oracle:thin:@192.168.57.62:1521:orcl, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 36000, maxIdleTimeExcessConnections -> 1800, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, preferredTestQuery -> null, privilegeSpawnedThreads -> false, properties -> {user=******, password=******}, propertyCycle -> 0, statementCacheNumDeferredCloseThreads -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, userOverrides -> {}, usesTraditionalReflectiveProxies -> false ]
Hibernate: select tbdxpuserl0_.SESSION_ID as SESSION_ID1_1_, tbdxpuserl0_.CREATE_TIME as CREATE_TIME2_1_, tbdxpuserl0_.IP_ADDR as IP_ADDR3_1_, tbdxpuserl0_.LOGIN_TIME as LOGIN_TIME4_1_, tbdxpuserl0_.status as status5_1_, tbdxpuserl0_.USER_ID as USER_ID6_1_, tbdxpuserl0_.username as username7_1_ from TB_DXP_USER_LOGIN_STATUS tbdxpuserl0_
2015-06-09 09:54:25,555 INFO ClassPathXmlApplicationContext - Closing org.springframework.context.support.ClassPathXmlApplicationContext@2e52cdcc: startup date [Tue Jun 09 09:43:51 CST 2015]; root of context hierarchy
2015-06-09 09:54:25,556 INFO EhCacheManagerFactoryBean - Shutting down EhCache CacheManager
2015-06-09 09:54:25,574 INFO SimpleHanlder - Stop socket handler.
2015-06-09 09:54:25,576 INFO LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'Oracle'
2015-06-09 09:54:25,579 INFO ShutDownHook - Socket server shutdown
此方法能夠?qū)嵢缃裣到y(tǒng)退出時(shí)對(duì)資源的關(guān)閉及緩存數(shù)據(jù)清理等功能。是一個(gè)很使用的功能。
文中部分內(nèi)容來(lái)自其它博文,代碼是我項(xiàng)目中的代碼。
如有雷同。請(qǐng)勿見(jiàn)怪。
本文僅僅介紹怎樣使用。至于原理請(qǐng)問(wèn)度娘和谷歌
posted on 2018-01-11 19:45 cynchanpin 閱讀(2862) 評(píng)論(0) 收藏 舉報(bào)
浙公網(wǎng)安備 33010602011771號(hào)