Jrebel 6.3.0を使用して、MybatisのMapper XMLをSpringブートWebアプリケーションにホットリロードします。そして私はMybatisを設定するためにJava Configurationを使いました。Jrebelは、Mapper XMLファイルをリロードするときに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;
}
私はマッパーXMLファイルを再ロードするときJrebelはインターセプタをクリアすることがわかりました。
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をできるようにとにかくはありますか?
は、あなたの問題への解決を見つけたことがありますか? – patryk
私はjrebelを変更せず、mybatisで1つのクラスを変更するだけでした。 org.apache.ibatis.builder.xml.XMLMapperBuilder。メソッドの終わりにpublic void parse(){ を追加します。//によって追加されました。 } if(configuration.getInterceptors()。size()== 0){ for(インターセプタインターセプタ:インターセプタ){ configuration.addInterceptor(インターセプタ); } } –
クラス自体を変更しましたか?あるいは、あなたのコードにXMLMapperBuilderを拡張し、mybatisがあなたが書いたものと何らかの形で置き換える新しいクラスを作成する方法がありますか? – patryk