在寫一個工具類的時候遇到問題:使用@Autowired無法自動注入bean。報空指針異常,獲取到的對象值爲null。
經過一番摸索實踐,探究到根本原因:工具類使用@Autowired無法注入bean的原因大多是因爲使用了靜態方法,相應的,使用@Autowired注入的對象也應該被static修飾,這樣spring就無法正常注入bean,找到了原因,我也總結了三種解決方法。
第一種是我認爲最簡單的方法,如下,因爲使用了static修飾的原因導致報錯,直接去掉star的static修飾和方法的static修飾,然後把工具類交給spring管理即可。
package ts.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class TestUtil {
@Autowired
// private static Star star;
private Star star;
// public static void testStar() {
// star.do1();
// }
public void testStar() {
star.do1();
}
}
spring配置文件需掃描工具類包
<context:component-scan base-package="ts.util" />
相應的使用時需注入TestUtil。
@Autowired
TestUtil testUtil;
public void test02() {
testUtil.testStar();
}
第二種方法,就是在構造函數上使用@Autowired。
package ts.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class TestUtil {
private static Star star;
@Autowired
public TestUtil(Star star) {
TestUtil.star = star;
}
public static void testStar() {
star.do1();
}
}
@Autowired 註解,可以對類成員變量、方法及構造函數進行標註,完成自動裝配的工作。
使用時直接調用即可。
public void test02() {
TestUtil.testStar();
}
第三種方法,使用@PostConstruct註解
package ts.util;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class TestUtil {
private static Star star;
@Autowired
private Star sta2;
@PostConstruct
public void init() {
star = sta2;
}
public static void testStar() {
star.do1();
}
}
@PostConstruct:被@PostConstruct修飾的方法會在服務器加載Servle的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之後執行,init()方法之前執行。
使用時直接調用即可。
public void test02() {
TestUtil.testStar();
}
總結:總的來說,靜態變量、靜態方法不是對象的屬性,而是一個類的屬性,所以靜態方法是屬於類(class)的,普通方法纔是屬於實體對象(也就是New出來的對象)的,spring注入是在容器中實例化對象的,並且靜態是優先於對象存在的,所以直接在靜態方法中調用注入的靜態變量其實是爲null的。歸根結底,sping中如果要對靜態變量進行注入只能是變相、間接的來完成。