一、背景
SpringBoot项目,使用了Mybatis-plus的MybatisSqlSessionFactoryBean去生成SqlSessionFactory的Bean,其中设置了TypeAliasesPackage,在IDEA里直接运行可以正常启动,打包运行就报entity的别名找不到。
//配置sqlSessionFactory的bean,设置分页拦截配置
@Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage("com.×××.×××.×××.entity");
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.addInterceptor(new PaginationInterceptor());
        bean.setConfiguration(configuration);
        return bean.getObject();
    }***mapper.xml里面 使用别名:
二、排查问题
maven将代码打包成jar,在idea内debug模式运行jar(添加JAR application即可):
- debug进入 - bean.getObject()中;
- 执行 - afterPropertiesSet(),启动调用- buildSqlSessionFactory()生成sqlSessionFactory,其中就有解析typeAliasesPackage的部分
- 在往下,会使用DefaultVFS解析文件,DefaultVFS发现需要解析的是个jar,然后就开启jar的读取流,查看根据内部的文件夹,去匹配要扫描文件夹TypeAliasesPackage,然后读取文件夹下的class文件名,将其拼接到TypeAliasesPackage后面,反射生成class,存放到一个set中。 
- 最后将Set中的Class维护到TypeAliasRegistry中的typeAliases中。typeAliases是个Map,key为小写的类名简称,value为Class对象。 
问题出现在了第3步,在jar的debug运行时,DefaultVFS没有读取到匹配的包名,因为SpringBoot打的包目录结构如下,DefaultVFS匹配直接从第一级目录开始匹配,所以未找到。
而在IDEA中直接编译运行时,其读取的是target中的classes下的目录,就可以找到对应的包名,注册成功别名。
-BOOT-INF
  -classes
    -com.×××.×××.×××
    -mapper
    -log4j.xml
    -application.yaml
  -lib
-META-INF
-org.springframework.boot.loader三、解决办法
在使用VFS读取文件是List<String> children = VFS.getInstance().list(path),在getInstance()中,优先使用了VFS.USER_IMPLEMENTATIONS维护的VFS实例,这个可用通过VFS.addImplClass(Class<? extends VFS> clazz)设置,其中Mybatis-plus与SpringBoot均提供了VFS的实现SpringBootVFS,在配置MybatisSqlSessionFactoryBean.getObject前设置VFS.addImplClass(new SpringBootVFS());即可。