构造器Autowire 导致循环引用的问题

2018-05-27  本文已影响0人  wuuuhaooo

循环依赖

遇到一个Spring项目启动报beans循环依赖的问题

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   mainController (field private me.ricardo.spring.test1.service.FirstService me.ricardo.spring.test1.controller.MainController.firstService)
      ↓
   firstService defined in file [xxx/FirstService.class]
┌─────┐
|  secondService defined in file [xxx/SecondService.class]
└─────┘

一开始很奇怪,经常有这种两个Class相互依赖的情况,先占个位再初始化。这就是两个很简单的service好像也没写构造方法。

仔细回想了一下突然想到确实写了构造方法,是因为IDE提示不要对变量进行Autowired:

Spring Team recommends "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies"

@Autowired
private FirstService firstService;
@Autowired
private SecondService secondService;

即推荐使用构造方法注入bean依赖,应该是为了防止有构造方法时出现NPE问题。Spring会先执行构造方法再用setter方法装配,下面这种情况就会出现空指针问题:

@Autowired
private SecondService secondService;
public MainController() {
    secondService.test();
}

强迫症患者习惯性option+enter,变成了:

FirstService.java:
@Autowired
public SecondService(FirstService firstService) {
    this.firstService = firstService;
}

SecondService.java:
@Autowired
public FirstService(SecondService secondService) {
    this.secondService = secondService;
}

两个Class构造的时候发生了循环依赖,测试把其中一个改成之前对变量装配的方法就没问题了:

FirstService.java:
@Autowired
SecondService secondService;

SecondService.java:
@Autowired
public SecondService(FirstService firstService) {
    this.firstService = firstService;
}

End

Autowired给Bean管理带来很多方便,但两种方法都有要注意的地方,一个是空指针问题,一个是循环依赖。Spring文档应该会有这些说明和举例,以前看的不够仔细,现在开始认真的重看一遍。

上一篇下一篇

猜你喜欢

热点阅读