我正在开发一个基于Eclipse 3.7 RCP的应用程序,它有多个模块。模块A是一堆库,包括mybatis-3.2.2.jar。模块B依赖于模块A(manifest.mf中的Require-Bundle),并且具有使用MyBatis访问数据库中数据的代码。我已经在模块B中导出了带有映射器类和XML的包,并将它们导入到模块A中。我在代码中构建了SqlSessionFactory,如果我按名称添加所有Mapper类,它可以正常工作,例如
configuration.addMapper(MyMapper.class);
然而,当我尝试在包中添加所有Mappers时:
configuration.addMappers(MyMapper.class.getPackage().getName());
MyBatis没有看到它们。
我尝试更改默认的类加载器,但这没有帮助。
Resources.setDefaultClassLoader(this.getClass().getClassLoader());
我怀疑这个问题与OSGI环境中类的可见性有关。如果是这种情况,有没有办法在应用程序中修复它?
答案 0 :(得分:2)
你试过吗
Resources.setDefaultClassLoader(Activator.class.getClassLoader())
。我认为这将使用OSGi类加载器。希望这会有所帮助。
答案 1 :(得分:1)
configuration.addMappers使用自己的ResolverUtil,它使用Thread上下文类加载器。 (至少在mybatis3中)。
最好的办法是编写自己的扫描代码并直接使用addMapper。我的参考资料和例子如下:
编辑:以下是mybatis 3.2.2的一些
但同样适用。
答案 2 :(得分:1)
我在Felix OSGi环境中遇到了与Spring Data JPA类似的问题。在这种情况下,我能够覆盖工厂类并将其添加到违规方法中:
ClassLoader pre = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(context.getClassLoader());
// add mappers here or call super method
} finally {
Thread.currentThread().setContextClassLoader(pre);
}
在这种情况下" context"是一个Spring上下文,但你应该能够从BundleWiring获得Module B的类加载器。
Bundle bundle; //get this by symbolic name if you don't have a reference
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
bundleWiring.getClassLoader();
希望addMappers方法不需要在同一个调用中访问模块A的类加载器。如果是这样的话,那么除非有扩展和注入不同Configuration或MapperRegistry类的方法,否则你无法做到这一点。