案例 1 :构造器内抛空指针异常
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LightMgrService {
@Autowired
private LightService lightService;
public LightMgrService() {
lightService.check();
}
}
@Service
public class LightService {
public void start() {
System.out.println("turn on all lights");
}
public void shutdown() {
System.out.println("turn off all lights");
}
public void check() {
System.out.println("check all lights");
}
}
在LightMgrService类初始化时,调用LightService的check方法去执行检查业务,从而输出"check all lights"。但结果确会抛出空指针。如下图所示:

image.png
Spring以上面这种写法去初始化对象,其过程是先实例化bean,注入bean依赖,再初始化bean。而默认构造器是再实例化的时候被自动调用的,此时,还未注入bean依赖,LightMgrService的属性LightService还是null,空指针异常也是正常的。有三种解决办法:
一是可以隐式注入,@Autowired注解引发的装配行为是在调用构造器之后的,隐式注入很好的解决了这个问题。
@Component
public class LightMgrService {
private LightService lightService;
public LightMgrService(LightService lightService) {
this.lightService = lightService;
lightService.check();
}
}
二是可以使用@PostConstruct注解。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LightMgrService {
@Autowired
private LightService lightService;
@PostConstruct
public void init() {
lightService.check();
}
}
三是实现InitializingBean接口,重写其afterPropertiesSet()方法。
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class LightMgrService implements InitializingBean {
@Autowired
private LightService lightService;
@Override
public void afterPropertiesSet() throws Exception {
lightService.check();
}
}