前言
項目中為了提高系統(tǒng)響應(yīng)速度經(jīng)常把熱數(shù)據(jù)存入緩存中如redis汽抚,memcached中。本文介紹一種使用的項目啟動加載緩存的方法
基本配置
1.思路
應(yīng)用啟動時加載緩存常用的方法有:
- 編寫linstener監(jiān)聽?wèi)?yīng)用啟動
- Bean實現(xiàn)InitializingBean接口陕凹,并實現(xiàn)afterPropertiesSet()方法
- 在Bean的init-method中進(jìn)行邏輯代碼編寫
- 。。先誉。拌阴。绍绘。
2.相關(guān)配置
本文采用實現(xiàn)InitializingBean接口,并實現(xiàn)afterPropertiesSet()方法的方式迟赃。
spring初始化bean的時候陪拘,如果bean實現(xiàn)了InitializingBean接口,會自動調(diào)用afterPropertiesSet方法纤壁,并且afterPropertiesSet方法優(yōu)先于init-method方法執(zhí)行
可參考Spring AbstractAutowireCapableBeanFactory中的實現(xiàn)
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
boolean isInitializingBean = bean instanceof InitializingBean;
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
((InitializingBean)bean).afterPropertiesSet();
return null;
}
}, this.getAccessControlContext());
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
((InitializingBean)bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
this.invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
3.代碼實現(xiàn)
為了代碼的可用性左刽,設(shè)計CacheInterface接口
public interface CacheInterface {
/**
* 實現(xiàn)接口在應(yīng)用啟動時加載熱數(shù)據(jù)
*
* @return
*/
boolean loadCache();
boolean deleteCache();
}
加載熱數(shù)據(jù)時實現(xiàn)CacheInterface接口
@Service
public class DemoLoadCache implements CacheInterface {
@Override
public boolean loadCache() {
//TODO 從關(guān)系型數(shù)據(jù)庫中查詢相關(guān)的數(shù)據(jù)并存儲到緩存中。
return true;
}
@Override
public boolean deleteCache() {
return false;
}
}
將所有實現(xiàn)CacheInterface接口的加載熱數(shù)據(jù)類注入到處理類中酌媒,實際應(yīng)用中考慮使用線程池欠痴。
@Service
public class CacheLoadService implements Runnable, InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(CacheLoadService.class);
@Autowired
private List<CacheInterface> cacheInterfaceList;
@Override
public void run() {
logger.info("start load cache");
long start = System.currentTimeMillis();
if (cacheInterfaceList != null && cacheInterfaceList.size() > 0) {
for (CacheInterface cacheInterface : cacheInterfaceList) {
cacheInterface.loadCache();
}
}
long end = System.currentTimeMillis();
logger.info("load cache finished in {}秒 ", (end - start) / 1000);
}
@Override
public void afterPropertiesSet() throws Exception {
Thread t = new Thread(this);
t.start();
}
}
Spring應(yīng)用啟動的時候,調(diào)用CacheLoadService中afterPropertiesSet方法啟動線程加載熱數(shù)據(jù)秒咨。
結(jié)尾
實際應(yīng)用中考慮真是場景考慮加載數(shù)據(jù)的方式喇辽。對熱數(shù)據(jù)的增刪改也要同步到緩存中。