MyBatis扫描通过VFS来实现
在Spring Boot中,由于是嵌套Jar,导致Mybatis默认的VFS实现DefaultVFS无法扫描嵌套Jar中的类。
解决办法,实现自定义的VFS,参考DefaultVFS增加对Spring Boot嵌套JAR的处理。
https://github.com/mybatis/mybatis-3/issues/325
https://github.com/StripesFramework/stripes/issues/35
1。
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import org.springframework.util.ResourceUtils;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.stripes.vfs.DefaultVFS;
@Slf4j
public class SpringBootVfs extends DefaultVFS {
@Override
protected URL findJarForResource(URL url) throws MalformedURLException {
url = ResourceUtils.extractJarFileURL(url);
return (isJar(url)) ? url : null;
}
@Override
protected boolean isJar(URL url) {
return url.getPath().toLowerCase().endsWith(ResourceUtils.JAR_FILE_EXTENSION)
|| url.getPath().toLowerCase().endsWith(".war");
}
/**
* List the names of the entries in the given {@link JarInputStream} that
* begin with the specified {@code path}. Entries will match with or without
* a leading slash.
*
* @param jar The JAR input stream
* @param path The leading path to match
* @return The names of all the matching entries
* @throws IOException If I/O errors occur
*/
@Override
protected List<String> listResources(JarInputStream jar, String path) throws IOException {
// Include the leading and trailing slash when matching names
if (!path.startsWith("/"))
path = "/" + path;
if (!path.endsWith("/"))
path = path + "/";
// Iterate over the entries and collect those that begin with the
// requested path
List<String> resources = new ArrayList<String>();
for (JarEntry entry; (entry = jar.getNextJarEntry()) != null;) {
if (!entry.isDirectory()) {
// Add leading slash if it's missing
String name = entry.getName();
if (!name.startsWith("/"))
name = "/" + name;
// Check file name
if (name.startsWith(path) || name.startsWith("/WEB-INF/classes" + path)) {
log.trace("Found resource: ", name);
resources.add(name.substring(1)); // Trim leading slash
}
}
}
return resources;
}
}
2在创建sqlSessionFactoryBean时
加入
VFS.addImplClass(SpringBootVFS.class);
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactoryBean() {
//解决myBatis下 不能嵌套jar文件的问题
VFS.addImplClass(SpringBootVFS.class);
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("org.weichai");
// 分页插件
PageHelper pageHelper = new PageHelper();
Properties props = new Properties();
props.setProperty("reasonable", "true");
props.setProperty("supportMethodsArguments", "true");
props.setProperty("returnPageInfo", "check");
props.setProperty("params", "count=countSql");
pageHelper.setProperties(props);
//添加XML目录
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
// 添加插件
bean.setPlugins(new Interceptor[] { pageHelper });
bean.setMapperLocations(resolver.getResources("classpath*:mapper/**/*.xml"));
return bean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}