工具类静态方法以及new关键字创建的对象,访问类中@Autowired注入的成员变量导致空指针

1,428 阅读2分钟

一.工具类静态方法调用使用@Autowired注入的bean导致的空指针问题

  • 问题描述:在工具类中使用@Autowired注入的bean报空指针

  • 原因:静态变量,静态方法不是对象的属性,属于class的;普通方法才是属于对象;spring注入是在容器中实例化对象,静态类,方法的加载优于@Autowired的加载(Java变量的初始化顺序为:静态变量或静态语句块–>实例变量或初始化语句块–>构造方法–>@Autowired> @PostConstruct)

解决办法:

  • @PostConstruct:被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。

/**
**@Component注解必不可少
**/
@Component
public class EnCodeUtils {

    @Autowired
    private AlarmRuleMapper alarmRuleMapper;


    private static EnCodeUtils enCodeUtils;

    @PostConstruct
    public void init() {
        enCodeUtils = this;
        enCodeUtils.alarmRuleMapper = this.alarmRuleMapper;
    }

  • 第二种方法,就是在构造函数上使用@Autowired。
@Component
public class EnCodeUtils {

  
    private static AlarmRuleMapper alarmRuleMapper;
   
    public EnCodeUtils() {
        EnCodeUtils.alarmRuleMapper = this.alarmRuleMapper;
    }

  • 第三种方法:spring配置文件需扫描工具类包
@SpringBootApplication(scanBasePackages = {"com.bigdata.servicebus.util"})

二.访问类中@Autowired注入的成员变量导致空指针

  • 问题描述:在除三层调用的地方使用@Autowired调用其他类对象
  • 原因:一个内含有@Autowired注解的Bean,我们必须要通过Spring的方式来获得这个Bean,而不能自己new一个。因为自己new出来的bean无法通过Spring容器来获得自己需要的bean.可以简单的理解为,要就全都使用Spring容器来管理,要不都不用,你自己new的东西没有进入Spring容器的门票

解决方案:

  • 方法一:传参
public class ServiceCallsImpl implements Strategy {

    private AnalysisService analysisService;

    public ServiceCallsImpl(AnalysisService analysisService) {
        this.analysisService = analysisService;
    }
  • 方法二:使用反射
public class ServiceCallsImpl implements Strategy {

    private AnalysisService analysisService;

    public ServiceCallsImpl() throws ClassNotFoundException {
        this.analysisService = this.getClass().getClassLoader().loadClass("com.bigdata.servicebus.analysis.record.AnalysisService").newInstance();
    }
  • 方法三:接口传参,在需要该对象的地方实现该接口,传参导入
public interface Strategy {
    boolean alarmDeal(AlarmLeft alarmLeft, RequestRecord requestRecord, MongoTemplate mongoTemplate);
    void setAnalysisService(AnalysisService analysisService);
}