原因
- 配置缺失,比如為開啟注解掃描驅動、注入組件為注冊;
- 使用 new 關鍵字創建的對象不受spring容器管理,無法注入;
- 注入靜態變量, 靜態變量/類變量不是對象的屬性,而是一個類的屬性,spring則是基於對象層面上的依賴注入。
。
懂的直接上代碼先
靜態注入的三種方式
在一些工具類中可能會依賴 service 層的對象,一般情況下工具類都是使用靜態方法,對應的成員變量也需要聲明為靜態的,此時如果直接使用 @Autowired 進行依賴注入,在方法調用的時候會報 NullpointerException.
@Autowired private static AdvancedDatastore dsForRW;
可以試一下,dsForRW在這種狀態下不能夠被依賴注入,會拋出運行時異常java.lang.NullPointerException,為什么呢?靜態變量/類變量不是對象的屬性,而是一個類的屬性,spring則是基於對象層面上的依賴注入。
但是自己比較喜歡封裝工具類,並通過@Component注解成功能組件,但是功能組件中的方法一般都是靜態方法,靜態方法只能調用靜態成員變量,於是就有了下面的問題。封有的時候封裝功能組件會需要底層的service注入,怎么辦呢?
去網上搜了下解決辦法,簡單總結一下幾種實現方式;
1.xml方式實現 這種方式適合基於XML配置的WEB項目; <bean id="mongoFileOperationUtil" class="com.*.*.MongoFileOperationUtil" init-method="init"> <property name="dsForRW" ref="dsForRW"/> </bean> 1 2 3 public class MongoFileOperationUtil { private static AdvancedDatastore dsForRW; private static MongoFileOperationUtil mongoFileOperationUtil; public void init() { mongoFileOperationUtil = this; mongoFileOperationUtil.dsForRW = this.dsForRW; } }
2.@PostConstruct方式實現
import org.mongodb.morphia.AdvancedDatastore; import org.springframework.beans.factory.annotation.Autowired; @Component public class MongoFileOperationUtil { @Autowired private static AdvancedDatastore dsForRW; private static MongoFileOperationUtil mongoFileOperationUtil; @PostConstruct public void init() { mongoFileOperationUtil = this; mongoFileOperationUtil.dsForRW = this.dsForRW; } }
@PostConstruct 注解的方法在加載類的構造函數之后執行,也就是在加載了構造函數之后,執行init方法;(@PreDestroy 注解定義容器銷毀之前的所做的操作)
這種方式和在xml中配置 init-method和 destory-method方法差不多,定義spring 容器在初始化bean 和容器銷毀之前的所做的操作;
3.set方法上添加@Autowired注解,類定義上添加@Component注解
import org.mongodb.morphia.AdvancedDatastore; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MongoFileOperationUtil { private static AdvancedDatastore dsForRW; @Autowired public void setDatastore(AdvancedDatastore dsForRW) { MongoFileOperationUtil.dsForRW = dsForRW; } } 首先Spring要能掃描到AdvancedDatastore的bean,然后通過setter方法注入; 然后注意:成員變量上不需要再添加@Autowired注解;