美文网首页
spring@Autowired注入——循环依赖遇到的坑

spring@Autowired注入——循环依赖遇到的坑

作者: andycheng | 来源:发表于2020-09-16 16:41 被阅读0次

    最近开发遇到一个问题,IDEA服务启动卡住了,找不到具体问题,启动spring boot服务,日志打印到AutowiredAnnotationBeanPostProcessor然后就卡住不动,日志如下:

    2020-09-16T15:49:08.315+0800 INFO [main] o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.<init>:155 - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2020-09-16T15:49:08.740+0800 INFO [pool-5-thread-1] m.s.i.schedule.IFTTTScheduleService.refreshProductIFTTT:162 - ProductIFTTT query start
    2020-09-16T15:49:08.741+0800 INFO [pool-5-thread-2] m.s.i.schedule.IFTTTScheduleService.refreshOpenProduct:145 - openProducts query start
    2020-09-16T15:49:08.741+0800 INFO [pool-5-thread-3] m.s.i.schedule.IFTTTScheduleService.refreshPythonRules:131 - BuiltInScript query start
    2020-09-16T15:49:08.741+0800 INFO [pool-5-thread-4] m.s.i.schedule.IFTTTScheduleService.refreshCustomRules:111 - CustomRule query start
    2020-09-16T15:49:08.743+0800 INFO [pool-5-thread-2] o.s.c.a.AnnotationConfigApplicationContext.prepareRefresh:583 - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6bb316cf: startup date [Wed Sep 16 15:49:08 CST 2020]; parent: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6fbc1bb
    2020-09-16T15:49:08.779+0800 INFO [pool-5-thread-2] o.s.b.f.a.AutowiredAnnotationBeanPostProcessor.<init>:155 - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring

    通过IDEA的Get Thread Dump功能看到线程在等待:

    Get Thread Dump

    通过Get Thread Dump查看线程中卡在的方法,发现卡是启动时,线程中的查询方法。

    refreshOpenProduct方法
    findAllProductIFTTT
    DefaultSingletonBeanRegistry.getSingleton
    AbstractApplicationEventMulticaster.getApplicationListeners

    怀疑是线程的问题,去掉线程,直接调用方法,没问题。确定是加了线程导致的问题。换了一个方法暂时解决。但是需要弄清楚问题的本质,从源头解决。


    出现问题的线程池

    改写注入方法

    怀疑是:可能是因为用线程池导致对象被多次注入。基于此,改写了使用线程池的服务的注入方法,去掉@Autowired,使用构造方法注入。

    使用@Autowired注入
    使用构造方法注入依赖

    重新启动,观察

    可以看到,启动报错了,提示服务循环依赖,真相大白!!这代码写得有点乱,把这个依赖的服务查询放到另外的服务中,去掉依赖,重启服务,问题消失,解决!收工!


    启动报错

    后记

    @Autowired注入,服务启动检查不到循环依赖,所以推荐使用更严谨的写法,在构造方法的时候把依赖的服务注入。


    关于线程中服务出现循环依赖,导致的服务启动线程卡住,具体原因需要分析spring的启动过程以及 线程池相关知识。

    今天的教程就到这里,喜欢的话,欢迎点赞,谢谢!

    相关文章

      网友评论

          本文标题:spring@Autowired注入——循环依赖遇到的坑

          本文链接:https://www.haomeiwen.com/subject/ikqhyktx.html