2016-07-28 29 views
1

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をできるようにとにかくはありますか?

+0

は、あなたの問題への解決を見つけたことがありますか? – patryk

+1

私はjrebelを変更せず、mybatisで1つのクラスを変更するだけでした。 org.apache.ibatis.builder.xml.XMLMapperBuilder。メソッドの終わりにpublic void parse(){ を追加します。//によって追加されました。 } if(configuration.getInterceptors()。size()== 0){ for(インターセプタインターセプタ:インターセプタ){ configuration.addInterceptor(インターセプタ); } } –

+0

クラス自体を変更しましたか?あるいは、あなたのコードにXMLMapperBuilderを拡張し、mybatisがあなたが書いたものと何らかの形で置き換える新しいクラスを作成する方法がありますか? – patryk

答えて

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); 
      } 
     } 
    } 
... 
} 
関連する問題