問題:靜態方法中注入bean
分析問題:先看一段代碼
@Component
public class ScriptExecuteContent {
@Autowired
private static SignRepository signRepository;
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
該段代碼晃眼一看沒啥問題,但是運行就會null異常,因爲此處注入的signRepository爲null,這是因爲靜態方法是屬於類的,普通方法才屬於對象,spring注入是在容器中實例化變量的,並且靜態是優先於對象存在的,所以直接在靜態方法中調用注入的靜態變量其實是爲null的,針對這點不太明白的,可以自行補一下java基礎。
但是現實當中我們很多情況需要再靜態方法中調用注入的bean對象,要怎麼樣實現呢?我目前知道的有兩種方法。
解決問題:
1. @Autowired 用在構造函數上
我們知道@Autowired 註釋,可以對類成員變量、方法及構造函數進行標註,完成自動裝配的工作,此種方式就是在構造函數上使用@Autowired。
代碼參考:
@Component
public class ScriptExecuteContent {
private static SignRepository signRepository;
@Autowired
public ScriptExecuteContent(SignRepository signRepository) {
ScriptExecuteContent.signRepository = signRepository;
}
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
2. 使用 @PostConstruct 註解
@PostConstruct是Java EE 5引入來影響Servlet生命週期的註解,被用來修飾非靜態的void()方法,@PostConstruct在構造函數之後執行,init()方法之前執行。
代碼參考:
@Component
public class ScriptExecuteContent {
@Autowired
private SignRepository signRepository;
private static ScriptExecuteContent scriptExecuteContent;
@PostConstruct
public void init() {
scriptExecuteContent = this;
scriptExecuteContent.signRepository = this.signRepository;
}
public static String checkSign(String certNo, String acctNo, String instCode) {
Sign sign = scriptExecuteContent.signRepository.findByCertNoAndAcctNoAndInstCode(certNo, acctNo, instCode);
if (null != sign
&& StringUtils.equals(sign.getStatus(), StatusEnum.SUCCESS.code())
&& DateUtil.getCurrentDate().before(sign.getExpireTime())) {
return "1";
} else {
return "0";
}
}
}
總結:以上兩種方式都能實現靜態方法中直接使用注入的bean對象,實現方式肯定不止這兩種,自己基礎差了,目前只知道這兩種。