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(註釋的方法)
相關文章
- Spring如何為靜態變數注入值Spring變數
- linux配置靜態路由解決網路問題Linux路由
- 靜態變數變數
- java執行緒安全問題之靜態變數、例項變數、區域性變數Java執行緒變數
- C語言第九周作業(指標變數,記憶體訪問,取址,空指標)C語言指標變數記憶體
- Dll堆疊問題(Dll的靜態變數與全域性變數、vs的MT與MD)變數
- 指標變數指標變數
- Mybatis系列:解決foreach標籤內list為空的問題MyBatis
- 寶塔部署靜態服務遇到問題與解決
- Linux配置靜態IP解決無法訪問網路問題Linux
- java.lang.NullPointerException 空指標異常問題JavaNullException指標
- 關於C++當中的指標懸空問題C++指標
- HttpCanary使用指南——靜態注入器HTTPPCA
- 【C++】靜態持續變數?如何建立靜態持續變數?C++變數
- 安卓開發中空指標問題 怎麼解決呢安卓指標
- 區域性變數和全域性變數(靜態和非靜態)區別變數
- const 變數和指標變數指標
- C語言函式傳遞指標引數的問題詳解C語言函式指標
- C語言指標(二) 指標變數 ----by xhxhC語言指標變數
- Java靜態變數在靜態方法內部無法改變值Java變數
- Laravel 在 Docker 環境下訪問 storage 靜態資源 404 問題解決LaravelDocker
- Linux CentOS 配置靜態 ip 和 解決 配置後無法聯網的問題LinuxCentOS
- 對於systemverilog靜態變數和動態變數 ,描述不正確的是()。變數
- 解決vue使用Sass時候的報錯問題Vue
- oracle 使用nullif解決除數為零的問題OracleNull
- 如何使用 DAX 函式解決動態圖表標題函式
- 記錄解決HttpServletResponse在引數報錯的問題HTTPServlet
- Java技巧-解決JAVA_HOME變數無效問題Java變數
- 空指標的傳說指標
- 防止空指標指標
- 使用API28報錯問題及解決API
- 直播網站原始碼,使用Scheduled做定時任務出現Autowired注入空指標網站原始碼指標
- 記一次Java自動拆箱引發的空指標問題Java指標
- 解決split無法得到空字串問題字串
- 被 C# 的 ThreadStatic 標記的靜態變數,都存放在哪裡了?C#thread變數
- 靜態測試解決方案
- 使用靜態住宅ip能解決多賬號防關聯問題?購買ip如何找到優質靜態住宅代理?
- 指標:存放記憶體地址的變數指標記憶體變數