MyBatis扫描通过VFS来实现
在Spring Boot中,由于是嵌套Jar,导致Mybatis默认的VFS实现DefaultVFS无法扫描嵌套Jar中的类。
解决办法,实现自定义的VFS,参考DefaultVFS增加对Spring Boot嵌套JAR的处理。
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;@Slf4jpublic 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 ListlistResources(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 resources = new ArrayList (); 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); } }