spingboot使用@Resource注入靜態變數報空指標的問題解決
昨天在工作中遇到這個問題,最後改為@Autowired解決,並找到了原理分析文章,記錄一下
一、業務場景
spring框架應用中有些靜態方法需要依賴被容器管理的類,就像這樣:
@Component
public class Test {
@Autowired
private static UserService userService;
public static void test() {
userService.test();
}
}
如果直接這樣去呼叫test()方法,那麼控制檯一定會報java.lang.IllegalStateException: @Resource annotation is not supported on static fields異常。
注意:這裡並不是spring未注入依賴,而是被static方法初始化時給清空了。
二、原理剖析
靜態變數、類變數,並不是物件的屬性,而是一個類的屬性;所以靜態方法是屬於整個類(class)的,普通方法才是屬於實體物件(也就是New出來的物件)的,spring注入是在容器中例項化物件,所以不能使用靜態方法。
而使用靜態變數、類變數擴大了靜態方法的使用範圍。在靜態方法中注入依賴在spring框架中是不推薦使用的,依賴注入的主要目的,是讓容器去產生一個物件的例項,然後在整個生命週期中使用他們,同時也讓測試工作更加容易。
一旦你使用靜態方法,就不再需要去產生這個類的例項,這會讓測試變得更加困難,同時你也不能為一個給定的類,依靠注入方式去產生多個具有不同的依賴環境的例項,這種static field是隱含共享的,並且是一種global全域性狀態,spring同樣不推薦這樣去做。
三、解決方法
1、將@Autowire加到構造方法上
@Component
public class Test {
private static UserService userService;
@Autowired
public Test(UserService userService) {
Test.userService = userService;
}
public static void test() {
userService.test();
}
}
2、用@PostConstruct註解
@Component
public class Test {
private static UserService userService;
@Autowired
private UserService userService2;
@PostConstruct
public void beforeInit() {
userService = userService2;
}
public static void test() {
userService.test();
}
}
四:@PostConstruct註解的說明
@PostConstruct該註解是javax.annotation包下的,被用來修飾一個非靜態的void()方法。被@PostConstruct修飾的方法會在伺服器載入Servlet的時候執行,並且只會被伺服器執行一次。PostConstruct在建構函式之後執行,init()方法之前執行。
@PostConstruct註釋規則:除了攔截器這個特殊情況以外,其他情況都不允許有引數,否則spring框架會報IllegalStateException;而且返回值要是void,但實際也可以有返回值,至少不會報錯,只會忽略
通常我們會是在Spring框架中使用到@PostConstruct註解 該註解的方法在整個Bean初始化中的執行順序:
Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(註釋的方法)
相關文章
- viewpager獲取當前view報空指標的解決方法Viewpager指標
- Spring如何為靜態變數注入值Spring變數
- 靜態變數和非靜態變數變數
- 空指標的救星指標
- 靜態變數變數
- 空指標的傳說指標
- 靜態變數與靜態方法變數
- 陣列和指標的問題陣列指標
- Java靜態變數塊使用案例Java變數
- java執行緒安全問題之靜態變數、例項變數、區域性變數Java執行緒變數
- linux配置靜態路由解決網路問題Linux路由
- asp.net中使用靜態變數ASP.NET變數
- 成員變數/函式指標的用法 (轉)變數函式指標
- 避免因在類中使用靜態函式而大量使用靜態變數 (轉)函式變數
- 指標問題的一點體會(區別 [指向指標的指標] 與 [指標的指標] .) (轉)指標
- 【C++】靜態持續變數?如何建立靜態持續變數?C++變數
- HttpCanary使用指南——靜態注入器HTTPPCA
- 靜態持續變數變數
- 靜態變數和Session變數Session
- 詳解c++指標的指標和指標的引用C++指標
- C: (pointer) 陣列變數和指標的區別陣列變數指標
- Dll堆疊問題(Dll的靜態變數與全域性變數、vs的MT與MD)變數
- C語言區域性變數、全域性變數、靜態區域性變數、靜態全域性變數C語言變數
- 關於例項變數和靜態變數的一點疑問變數
- 使用指標接收器時,值物件自動取指標的奇怪問題指標物件
- Linux配置靜態IP解決無法訪問網路問題Linux
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- 關於二維陣列指標的問題陣列指標
- static靜態變數的理解變數
- js中的靜態變數JS變數
- 靜態全域性變數和全域性變數變數
- 靜態變數和例項變數區別?變數
- Java靜態變數在靜態方法內部無法改變值Java變數
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- 資料庫連線池的問題,連線池物件為靜態變數有問題麼資料庫物件變數
- swap空間不足問題解決
- 解決dba_outstanding_alerts誤報表空間使用率的問題
- 全域性變數和靜態變數的區別變數