问题
@CacheNamespace 修饰的接口,例如MapperA,
要先与@CacheNamespaceRef(MapperA.class)修饰的接口加载
你遇到的问题是由于 Spring Boot 启动时,加载顺序导致 B 先加载,而 A 的缓存命名空间还没有被创建。这是 MyBatis 在解析 @CacheNamespaceRef 时的常见问题,因为它依赖于 A 的命名空间已经存在。
解决方案:
1. 确保加载顺序
可以通过以下方法确保 A 先于 B 加载:
- 分配加载顺序:可以通过使用 Spring 的
@DependsOn注解来显式声明依赖关系,确保B在A加载完之后才被加载。
例如:
@CacheNamespace
public interface AMapper {// A Mapper methods
}@CacheNamespaceRef(AMapper.class)
@DependsOn("AMapper") // 显式依赖A的加载
public interface BMapper {// B Mapper methods
}
@DependsOn可以确保B在A创建后才会被加载。
2. 使用 Spring Bean 的初始化顺序
在 Spring Boot 中,通过将 Mapper 注册为 Spring Bean,你可以控制它们的初始化顺序。
- 自定义
Mapper的加载顺序:
如果你使用@MapperScan来自动扫描Mapper,可以手动通过 Java Config 配置Mapper的初始化顺序。
例如:
@Configuration
public class MyBatisConfig {@Beanpublic AMapper aMapper(SqlSessionFactory sqlSessionFactory) {return sqlSessionFactory.getMapper(AMapper.class);}@Beanpublic BMapper bMapper(SqlSessionFactory sqlSessionFactory) {// 确保 AMapper 已经初始化aMapper(sqlSessionFactory);return sqlSessionFactory.getMapper(BMapper.class);}
}
这样确保了 AMapper 在 BMapper 之前被初始化。
3. 延迟加载 BMapper
你可以使用 @Lazy 注解延迟加载 BMapper,这样 BMapper 只有在需要时才会被加载,从而确保 AMapper 已经加载完成。
例如:
@CacheNamespace
public interface AMapper {// A Mapper methods
}@CacheNamespaceRef(AMapper.class)
@Lazy
public interface BMapper {// B Mapper methods
}
总结:
通过以上方法,你可以确保 B 的 Mapper 在 A 的命名空间创建完成后加载,解决 Spring Boot 启动时的加载顺序问题。