Spring Bean 生命周期常见错误

案例 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();
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容