靜態方法中調用@Autowired


一、背景

  1.今天寫代碼發現有一個使用@Component注解的util類,類中的方法都是static靜態修飾的,但是我要修改其中一個靜態方法,在靜態方法中我要調用一個service類,代碼如下

 修改前:

@Component
@Slf4j
public class TestUtil {
    
    private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";

    public static List<Integer> get() {
        return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
    }
}

 修改后

@Component
@Slf4j
public class TestUtil {
    
    private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
    private static final String SWITCH = "switch";

    @Autowired
    private static JobNeedCarrierQuery jobNeedCarrierQuery;


    public static List<Integer> get() {
        if(Lion.getBooleanValue(SWITCH)) {
            return jobNeedCarrierQuery.doQuery();
        }else {
            return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
        }
    }
}

  

二、問題

  當執行修改后的代碼后,發現報了空指針異常,debug發現jobNeedCarrierQuery沒有被注入對象,調用doQuery方法是報NPE

三、原因

  在 Java 中,針對 static 靜態成員,我們有一些最基本的常識:靜態變量(成員)它是屬於類的,而非屬於實例對象的屬性;同樣的靜態方法也是屬於類的,普通方法(實例方法)才屬於對象。而 Spring 容器管理的都是實例對象,包括它的@Autowired依賴注入的均是容器內的對象實例,所以對於 static 成員是不能直接使用@Autowired注入的。這很容易理解:類成員的初始化較早,並不需要依賴實例的創建,所以這個時候 Spring 容器可能都還沒“出生”,談何依賴注入呢?

四、解決方案

  

2.@PostConstruct方式實現

@Component (1)
@Slf4j
public class TestUtil {

    private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
    private static final String SWITCH = "switch";

    @Autowired. (2)
    private JobNeedCarrierQuery jobNeedCarrierQuery;

    private static TestUtil testUtil;  (3)

    @PostConstruct (4)
    public void init(){
        testUtil =  this;
        testUtil.jobNeedCarrierQuery = this.jobNeedCarrierQuery;
    }


    public static List<Integer> get() {
        if(Lion.getBooleanValue(SWITCH)) {
            return testUtil.jobNeedCarrierQuery.doQuery(BusinessLineEnum.SPOCK_BIKE.getCode()); (5)
        }else {
            return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16));
        }
    }
}

 

3.set方法上添加@Autowired注解,類定義上添加@Component注解

@Component  
public class TestUtil {      
   private static final String CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME = "test";
    private static final String SWITCH = "switch";


    private static JobNeedCarrierQuery jobNeedCarrierQuery;
  
  @Autowired
  public void setDatastore(JobNeedCarrierQuery jobNeedCarrierQuery) {
        TestUtil.jobNeedCarrierQuery=jobNeedCarrierQuery;
  }

public static List<Integer> get() { if(Lion.getBooleanValue(SWITCH)) { return jobNeedCarrierQuery.doQuery(); }else { return Lion.getList(CARRIER_MANDATORY_JOB_ID_LIST_CONFIG_NAME, Integer.class, ImmutableList.of(2, 5, 7, 14, 16)); } }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM