Spring注解注入失败问题

背景

做一个工具类时,报NullPointerException异常,debug后发现,注入的service为null。代码如下:

package com.gwall.utils;

public class StringReplaceUtil {

    @Resource
    private static SystRepository systRepository;

    public static String replace(String oldString) {

        SqlBuilder builder = new WhereBuilder();
        List systList = systRepository.findAllByWhere(builder);

        return "";
    }

}

解决过程

初步分析(静态变量)

因为注入的属性是static静态变量,所以初步断定是因为bean不允许注入到静态变量中。

尝试:

方案一:setter注入(推荐)

package com.gwall.utils;

public class StringReplaceUtil {


    private static SystRepository systRepository;

    public SystRepository getSystRepository() {
        return systRepository;
    }

    // spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
    @Resource
    public void setSystRepository(SystRepository systRepository) {
        StringReplaceUtil.systRepository = systRepository;
    }

    public static String replace(String oldString) {

        SqlBuilder builder = new WhereBuilder();
        List systList = systRepository.findAllByWhere(builder);

        return "";
    }

}

方案二:再定义一个变量注入

// 网上找到的解决方案,可以参考一下
public class Test {

    @Resource
    private SystRepository systRepository;

    private static SystRepository staticSystRepository;

    @PostConstruct
    void init() {
        staticSystRepository = systRepository;
    }

}

结果:

依然报错

第二步分析(spring扫描)

spring是通过组件扫描和自动装配来管理bean的。因为组件扫描需要配置扫描范围,所以要确定类是否在扫描范围内。

尝试:

根据配置把类转移到service扫描位置

package com.gwall.service.impl;

public class StringReplaceUtil {


    private static SystRepository systRepository;

    public SystRepository getSystRepository() {
        return systRepository;
    }

    // spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
    @Resource
    public void setSystRepository(SystRepository systRepository) {
        StringReplaceUtil.systRepository = systRepository;
    }

    public static String replace(String oldString) {

        SqlBuilder builder = new WhereBuilder();
        List systList = systRepository.findAllByWhere(builder);

        return "";
    }

}

结果:

依然报错

第三步分析(spring组件声明)

类要作为bean被spring发现、管理,首先应该声明为组件类

package com.gwall.service.impl;

@Service
public class StringReplaceUtil {


    private static SystRepository systRepository;

    public SystRepository getSystRepository() {
        return systRepository;
    }

    // spring注入不能注入到static属性中,所以用setter注入。放入Service中加入service注解,才能正确注入
    @Resource
    public void setSystRepository(SystRepository systRepository) {
        StringReplaceUtil.systRepository = systRepository;
    }

    public static String replace(String oldString) {

        SqlBuilder builder = new WhereBuilder();
        List systList = systRepository.findAllByWhere(builder);

        return "";
    }

}

尝试:

加上对应的组件声明注解(@Component@Controller@Service@Repository)

结果:

成功

总结

  1. 是否添加组件声明注解(@Component@Controller@Service@Repository)
  2. 是否在扫描范围内
  3. 是否注入到static变量

你可能感兴趣的:(spring)