一個類中的非靜態成員注入方式很是常見,但有一天我須要寫一個工具類,這個工具類中的方法都是靜態方法,所以成員必須是靜態成員。我用到了Redis查詢,獲取redis的方法並不是靜態方法,而是一個spring注入的bean。java
如何在靜態類(類中的方法都爲靜態)中,用spring注入靜態成員呢?redis
@Autowired private static RedisHelperManager redisHelperManager;
這樣確定是不行的!,而且在用到該變量時會拋出運行時異常java.lang.NullPointerException
,爲何呢?靜態變量不屬於對象的屬性,屬於類屬性,spring是基於對象層面的注入。spring
經過搜索,主要有如下三種實現方式:函數
@PostConstruct
方式注入@PostConstruct
方式的變形除第3種外,其餘都是從網上搜集整理。工具
有人說這是spring官方在乎識到對靜態變量支持不友好後推出的方式,我並無找到官方文檔,但它倒是能夠。也是一個最簡單且容易理解的方式。this
將註解放在setter方法之上code
@Component public class DistinctUtil { private static RedisHelper redisHelper; @Autowired public void setRedisHelper(RedisHelper redisHelper) { DistinctUtil.redisHelper = redisHelper; } public static void doDistinct() { redisHelper.sdiff(); } }
public class DistinctUtil { private static RedisHelper redisHelper; public void setRedisHelper(RedisHelper redisHelper) { DistinctUtil.redisHelper = redisHelper; } public static void doDistinct() { // 爲演示精簡代碼 redisHelper.sdiff(); } }
<bean class="cn.com.dotleo.DistinctUtil"> <property name="redisHelper" ref="redisHelper"/> </bean>
@PostConstruct
方式注入這種方式是我在網上搜到的另外一種注入方式,@PostConstruct
和 @PreDestroy
一個是在初始化以後調用,一個是在銷燬以前調用。這裏用到了@PostConstruct
,在初始化後將一個對象賦值給了該類的靜態變量。xml
@Component public class DistinctUtil { @Autowired private RedisHelper redisHelper; private static DistinctUtil distinctUtil; @PostConstruct public void init() { this.redisHelper = redisHelper; distinctUtil = this; } public static void doDistinct() { distinctUtil.redisHelper.sdiff(); } }
public class DistinctUtil { private RedisHelper redisHelper; private static DistinctUtil distinctUtil; public void init() { this.redisHelper = redisHelper; distinctUtil = this; } public static void doDistinct() { distinctUtil.redisHelper.sdiff(); } public void setRedisHelper(RedisHelper redisHelper) { this.redisHelper = redisHelper; }
<bean class="cn.com.dotleo.DistinctUtil" init-method="init"> <property name="redisHelper" ref="redisHelper"/> </bean>
@PostConstruct
方式的變形既然能夠在初始化以後賦值,那也必然能夠在初始化時賦值,所以想到了第三種方法。對象
##基於註解的方式文檔
@Component public class DistinctUtil { private static DistinctUtil instance; @Autowired private RedisHelper redisHelper; public DistinctUtil() { instance = this; } public static void doDistinct() { // 爲演示精簡代碼 instance.redisHelper.sdiff(); } }
這樣,spring注入一個DistinctUtil類,並自動注入RedisHelper,在構造函數中將該類賦值給了靜態的成員變量。以後能夠經過該成員變量調用注入的redisHelper的方法。
public class DistinctUtil { private static DistinctUtil instance; private RedisHelper redisHelper; public DistinctUtil(RedisHelper redisHelper) { this.redisHelper = redisHelper; instance = this; } public static void doDistinct() { // 爲演示精簡代碼 instance.redisHelper.sdiff(); } }
<bean class="cn.com.dotleo.DistinctUtil"> <constructor-arg name="redisHelper" ref="redisHelper"/> </bean>
因爲本人水平有限,只是從網上搜集方法並記錄備忘,若是能幫助到別人很是榮幸。但我並非很清楚這兩類方式(第1種爲一類,二、3種爲一類)的區別或者優缺點,煩請評論區賜教。