我正在使用Jrebel 6.3.0为我的Spring启动Web应用程序热重载Mybatis的Mapper XML。我使用Java配置来配置Mybatis。
@Configuration
@ConditionalOnClass({ PageInterceptor.class })
@EnableConfigurationProperties(MybatisPageProperties.class)
@AutoConfigureBefore(MybatisAutoConfiguration.class)
public class MyBatisPageAutoConfiguration implements ApplicationContextAware {
private static final Logger LOG = LoggerFactory.getLogger(MyBatisPageAutoConfiguration.class);
@Autowired
private MybatisPageProperties properties;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanUtil.setApplicationContext(applicationContext);
}
/**
*
*
* @return
*/
@Bean
public PageInterceptor pageInterceptor() {
LOG.info("========PageInterceptor========");
PageInterceptor pageInterceptor = new PageInterceptor();
Properties p = new Properties();
p.setProperty("dialect", properties.getDialect());
p.setProperty("sqlIdRegex", properties.getSqlIdRegex());
pageInterceptor.setProperties(p);
return pageInterceptor;
}
我发现Jrebel在重新加载mapper xml文件时会清除拦截器。
org.zeroturnaround.jrebel.mybatis.SqlMapReloader
private void reconfigure() {
log.infoEcho("Reloading SQL maps");
this.conf.reinit(); // Clear loadedResources and interceptors
reloadedResources.set(Collections.synchronizedSet(new HashSet()));
enterReloading();
try {
if (this.confBuilder != null)
this.confBuilder.reinit();
reconfigureAdditionalMappings();
exitReloading();
reloadedResources.remove();
}
finally
{
exitReloading();
reloadedResources.remove();
}
}
.........
private void reconfigureAdditionalMappings() {
for (ResourceDesc rd : (ResourceDesc[])this.additionalMappings.toArray(new ResourceDesc[0])) {
reconfigureMapping(rd);
}
}
private void reconfigureMapping(ResourceDesc rd) {
org.apache.ibatis.session.Configuration c = (org.apache.ibatis.session.Configuration)this.conf;
try { // Only reload loadedResources from Mapper XML files.
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(ResourceUtil.asInputStream(rd.url), c, rd.path, c.getSqlFragments());
xmlMapperBuilder.parse();
}
catch (Exception e) {
if ((e.getCause() instanceof java.io.FileNotFoundException)) removeMappingForDeletedResource(rd); else {
throw new RuntimeException("Failed to parse mapping resource: '" + rd.url + "'", e);
}
} finally {
ErrorContext.instance().reset();
}
}
org.zeroturnaround.jrebel.mybatis.cbp.ConfigurationCBP
public class ConfigurationCBP
extends JavassistClassBytecodeProcessor
{
public void process(ClassPool cp, ClassLoader cl, CtClass ctClass)
throws Exception
{
ctClass.addInterface(cp.get(JrConfiguration.class.getName()));
ctClass.addField(new CtField(cp.get(SqlMapReloader.class.getName()), "reloader", ctClass));
CtConstructor[] constructors = ctClass.getConstructors();
for (int i = 0; i < constructors.length; i++) {
CtConstructor constructor = constructors[i];
if (constructor.callsSuper()) {
constructor.insertAfter("reloader = new " + SqlMapReloader.class.getName() + "($0);");
}
}
ctClass.addMethod(CtNewMethod.make("public " + SqlMapReloader.class
.getName() + " getReloader() {" + " return reloader;" + "}", ctClass));
ctClass.addMethod(CtNewMethod.make("public void reinit() { loadedResources.clear(); ((" + JrInterceptorChain.class
.getName() + ") interceptorChain).jrClear();" + "}", ctClass));
ctClass.getDeclaredMethod("isResourceLoaded").insertAfter("if (reloader.doReload($1)) { loadedResources.remove($1); $_ = false;}");
}
}
有没有让Jrebel保留拦截器?
答案 0 :(得分:0)
我的项目是web应用程序,我们不需要在prod-env中进行此更改,我们只需在dev-env中使用jrebel,所以只需修改从源jar获取的源文件,并将其放在src / test中/ java,它将构建到类dir,并替换原始jar中的类。不要将它放在src / main / java文件夹中。
org.apache.ibatis.builder.xml.XMLMapperBuilder
...
public class XMLMapperBuilder extends BaseBuilder {
private static List<Interceptor> interceptors = new ArrayList<Interceptor>(); // Added by yuanjinyong
...
public void parse() {
...
parsePendingStatements();
// Added by yuanjinyong
if (interceptors.size() == 0) {
interceptors.addAll(configuration.getInterceptors());
}
if (configuration.getInterceptors().size() == 0) {
for (Interceptor interceptor : interceptors) {
configuration.addInterceptor(interceptor);
}
}
}
...
}