springboot 数据源依赖于mapper 导致循环引用报错

发布于 2022-09-13 00:25:17 字数 2037 浏览 25 评论 0

介绍情况

springboot项目,mybatis-plus 持久层框架

DynimcDatasource 依赖于 Mapper
Mapper 依赖于  SqlSessionFoctory
SqlSessionFactory 依赖于 DynimcDatasource

循环依赖报错 The dependencies of some of the beans in the application context form a cycle:

DynimcDatasource -> Mapper -> SqlSessionFoctory -> DynimcDatasource

bean生成方式

@Component
public class DynimcDatasource{
    @Resource
    private Mapper mapper;

    @PostConstruct
    public void init() {
        mapp.list();
        ...
    }
  ...
}

@Mapper
public interface Mapper extends BaseMapper<XXX>{
}

@Configuration
public class xxxConfig{

  @Bean(name = "sqlSessionFactory")
  public SqlSessionFactory sqlSessionFactory(DynamicDataSource 
    dynamicDataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new 
        MybatisSqlSessionFactoryBean();
        bean.setDataSource(dynamicDataSource);
        bean.setTransactionFactory(new 
        MultiDataSourceTransactionFactory());
        return bean.getObject();     
   }
        
}

奇怪的一个地方:

我在其他地方注入DynimcDatasource,和 Mapper之后,spring就能处理循环依赖了,

注入方式如下

@Configuration
public class xxxConfig{
  @Resource
  private DynimcDatasource dynimcDatasource;
  
  @Resource
  private Mapper mapper;
}
求解释原因。
并求问是否有更好的接触方案,感觉这么弄有点丑。

解决:循环引用的一个节点上注入对象时加@Lazy可以解决循环引用问题

@Configuration
public class xxxConfig{

  @Bean(name = "sqlSessionFactory")
  public SqlSessionFactory sqlSessionFactory(@Lazy DynamicDataSource 
    dynamicDataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new 
        MybatisSqlSessionFactoryBean();
        bean.setDataSource(dynamicDataSource);
        bean.setTransactionFactory(new 
        MultiDataSourceTransactionFactory());
        return bean.getObject();     
   }
        
}
保留的疑问:在不使用@Lazy时,为什么我在其他对象中注入了DynimcDatasource 和 Mapper 之后,spring就是解决循环依赖了呢

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月无声 2022-09-20 00:25:17

我最终的解决方案是这样的:生成sqlSessionFactory注入DynamicDataSource的时候用@Lazy懒加载。然后执行顺序就是,先创建sqlSessionFactory,最后创建DynamicDataDsource

@Configuration
public class xxxConfig{

  @Bean(name = "sqlSessionFactory")
  public SqlSessionFactory sqlSessionFactory(@Lazy DynamicDataSource 
    dynamicDataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new 
        MybatisSqlSessionFactoryBean();
        bean.setDataSource(dynamicDataSource);
        bean.setTransactionFactory(new 
        MultiDataSourceTransactionFactory());
        return bean.getObject();     
   }
        
}

反思:@Lazy是工程上的可行方案。 但实际底层的原因确实是依赖设计有问题。
我这边后来整理了逻辑,实际上是两个数据源,把这两个数据源的逻辑分开后就没有依赖问题了。 
* 原本是ormA+B -> 数据源A+B -> ormA+B。
* 整理后逻辑为 ormA-> 数据源A-> ormB -> 数据源B.
叹沉浮 2022-09-20 00:25:17

orm框架依赖数据源,数据源的优先级较高,然后你数据源里面又依赖orm框架的类,这不是无限套娃嘛!设计就有问题,先问问自己为什么要这么设计,如果只是为了初始化一部分数据,容器提供了一大堆扩展点

羞稚 2022-09-20 00:25:17

spring 是解决了循环依赖的问题的,除非你使用的是构造器注入的方式,才会出现循环依赖的报错。如果使用的是setter,字段注入的方式,并且bean是单例,spring 提供循环依赖的问题解决。我去测试了下,确实是可以解决。你可以关注下注入的方式。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文