通过一晚上的努力,终于成功了。但是个人认为解决的很丑陋。过程如下(请看完,最后有个说明)
1、增加一个ReloadableSqlMapClientFactoryBean,从spring的SqlMapClientFactoryBean复制所有代码
2、给这个FactoryBean增加public void reload()方法,两行:
this.setConfigLocation(new FileSystemResource(this.configLocation.getFile().getPath()));
this.afterPropertiesSet();
3、将applicationContext.xml中的sqlMapClient的class设置为ReloadableSqlMapClientFactoryBean
4、在自己的WEB程序下建立com.ibatis.common.resources.Resources类,不用说,拷贝人家原来的代码过来。
5、修改Resources.getResourceAsStream(ClassLoader loader, String resource),将
<<<<<<loader.getResourceAsStream(resource);//换成
>>>>>>loader.getResource(resource).openStream();
6、写一个jsp文件,得到ReloadableSqlMapClientFactoryBean,然后调用其reload方法,即可刷新。
在跟踪调试的过程中,主要遇到两个关卡:
一,第二步的第一行,是为了确保重新读取sql-map-config.xml。
二,前3步都很好理解,但是后面的就读了很久代码才搞明白。原来catalina的WebappClassLoader的getResourceAsStream是先读缓存(看tomcat的api可以知道),而iBatis是用这个方法来读取sql-map.xml的,导致配置文件内容被缓存。而用loader.getResource就可以。
在一个Web应用程序中,只在SqlMapClientBuilder中才会读取这些配置文件,一般情况下,只在启动时在调用,所以这样修改对实际应用没有任何影响。
我现在对java还没有什么实践经验,请各位前辈帮忙分析一下,这样做有没有意义?是否有什么隐患?或者有什么更帅的解决方法呢?
(BTW:可能有人会说“这样做根本没有任何价值”,因为业务模型应该是先经过测试并稳定的,sql映射在运行时不应该有任何改动。我自己也明白呵呵,但是觉得如果能实时的修改出来,不是更好吗?现在在IDE环境中,Class有时都能HotLoad,配置就更应该能手动刷新吧。。。。)