在SpringBoot下使用Mybatis-plus设置了TypeAliasesPackage,IDEA运行可以,但打包不生效

2022-07-08 08:58:41

一、背景

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即可):

  1. debug进入bean.getObject()中;

  2. 执行afterPropertiesSet(),启动调用buildSqlSessionFactory()生成sqlSessionFactory,其中就有解析typeAliasesPackage的部分

  3. 在往下,会使用DefaultVFS解析文件,DefaultVFS发现需要解析的是个jar,然后就开启jar的读取流,查看根据内部的文件夹,去匹配要扫描文件夹TypeAliasesPackage,然后读取文件夹下的class文件名,将其拼接到TypeAliasesPackage后面,反射生成class,存放到一个set中。

  4. 最后将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());即可

  • 作者:iijik55
  • 原文链接:https://blog.csdn.net/iijik55/article/details/123709059
    更新时间:2022-07-08 08:58:41