XMLMapperReLoader
import java.io.IOException;java
import java.io.InputStream;node
import java.io.InputStreamReader;spring
import java.lang.reflect.Field;sql
import java.util.ArrayList;apache
import java.util.HashMap;緩存
import java.util.List;app
import java.util.concurrent.Executors;dom
import java.util.concurrent.ScheduledExecutorService;ide
import java.util.concurrent.TimeUnit;ui
import org.dom4j.Node;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.orm.ibatis.SqlMapClientFactoryBean;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import com.gome.cm.util.DynamicDataSource;
import com.gome.cm.util.SpringContextUtil;
import com.gome.cm.util.StringUtils;
import com.gome.cm.util.dom4jXmlParseMgr;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
public class XMLMapperReLoader {
private Logger logger=Logger. getLogger(this.getClass());
List<Resource> mapperLocations;
SqlMapClientTemplate sqlMapClientTemplate;
private DynamicDataSource mydataSource;
private final String SQL_MAPPER_PATH="sql-map-config.xml" ;
private HashMap<String, String> fileMapping = new HashMap<String, String>();
private Scanner scanner = null;
private ScheduledExecutorService service = null;
public void afterPropertiesSet() throws Exception {
try {
service = Executors. newScheduledThreadPool(1);
sqlMapClientTemplate = (SqlMapClientTemplate)SpringContextUtil.getBean( "sqlMapClientTemplateMy");
mydataSource=(DynamicDataSource)SpringContextUtil.getBean( "mydataSource");
mapperLocations= new ArrayList<Resource>();
// 觸發文件監聽事件
scanner = new Scanner();
scanner.scan();
service.scheduleAtFixedRate( new Task(), 5, 5, TimeUnit.SECONDS);
} catch (Exception e1) {
e1.printStackTrace();
}
}
class Task implements Runnable {
@Override
public void run() {
try {
if ( scanner.isChanged()) {
logger.info( "*Mapper.xml文件改變,從新加載." );
scanner.reloadXML();
logger.info( "加載完畢.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Scanner {
public Scanner() {
dom4jXmlParseMgr dom4j = new dom4jXmlParseMgr(Thread.currentThread().getContextClassLoader().getResourceAsStream( SQL_MAPPER_PATH));
List<Node> nodeList= dom4j.getMuliElementNode("sqlMapConfig/sqlMap");
if(StringUtils. listNotEmpty(nodeList)){
for (Node node : nodeList) {
String resource=dom4j.getElementAttributeValue(node, "resource");
Resource ins= new FileSystemResource(Thread.currentThread().getContextClassLoader().getResource(resource).getFile());
mapperLocations.add(ins);
}
}
}
public void reloadXML() throws Exception {
Field field = SqlMapClientTemplate. class .getDeclaredField("sqlMapClient" );
field.setAccessible( true);
SqlMapClient sqlMapClient = (SqlMapClient) field.get(sqlMapClientTemplate);
Resource configLocation = new InputStreamResource(Thread.currentThread().getContextClassLoader().getResourceAsStream( SQL_MAPPER_PATH));
/* SqlMapClientFactoryBean beanFactory= new SqlMapClientFactoryBean();
beanFactory.setDataSource(mydataSource);
beanFactory.setConfigLocation(configLocation);
beanFactory.afterPropertiesSet();
sqlMapClientTemplate.setSqlMapClient(beanFactory.getObject());
*/
// 刷新緩存
sqlMapClient.flushDataCache();
sqlMapClient= SqlMapClientBuilder.buildSqlMapClient(configLocation.getInputStream());
sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
sqlMapClientTemplate.afterPropertiesSet();
}
public void scan() throws IOException {
if (! fileMapping.isEmpty()) {
return;
}
if ( mapperLocations!= null && mapperLocations.size()>0) {
Resource[] resources= new Resource[mapperLocations.size()];
resources = (Resource[])mapperLocations.toArray(resources);
if (resources != null) {
for ( int i = 0; i < resources.length; i++) {
String multi_key = getValue(resources[i]);
fileMapping.put(resources[i].getFilename(), multi_key);
}
}
}
}
private String getValue(Resource resource) throws IOException {
String contentLength = String.valueOf((resource.contentLength()));
String lastModified = String.valueOf((resource.lastModified()));
return new StringBuilder(contentLength).append(lastModified).toString();
}
public boolean isChanged() throws IOException {
boolean isChanged = false;
if ( mapperLocations!= null && mapperLocations.size()>0) {
Resource[] resources= new Resource[mapperLocations.size()];
resources = (Resource[])mapperLocations.toArray(resources);
for ( int i = 0; i < resources. length ; i++) {
String name = resources[i].getFilename();
String value = fileMapping.get(name);
String multi_key = getValue(resources[i]);
if (!multi_key.equals(value)) {
isChanged = true;
fileMapping.put(name, multi_key);
}
}
}
return isChanged;
}
}
public void destroy() throws Exception {
if ( service != null) {
service.shutdownNow();
}
}
}