构造器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文档应该会有这些说明和举例,以前看的不够仔细,现在开始认真的重看一遍。