在SpringBoot下使⽤Mybatis-plus设置了TypeAliasesPacka。
。。
⼀、背景
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.Resources("classpath:mapper/*.xml"));idea debug
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.addInterceptor(new PaginationInterceptor());
bean.setConfiguration(configuration);
Object();
}
***l⾥⾯ 使⽤别名:<update id="update" parameterType="UserEntity">
⼆、排查问题
maven将代码打包成jar,在idea内debug模式运⾏jar(添加JAR application即可):
1. debug进⼊Object()中;
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
-l
-application.yaml
-lib
-META-INF
-org.springframework.boot.loader
三、解决办法
在使⽤VFS读取⽂件是List<String> children = Instance().list(path),在getInstance()中,优先使⽤
了VFS.USER_IMPLEMENTATIONS维护的VFS实例,这个可⽤通过VFS.addImplClass(Class<? extends VFS> clazz)设置,其中Mybatis-plus与SpringBoot均提供了VFS的实现SpringBootVFS,在配置Object前设置VFS.addImplClass(new SpringBootVFS());即可。