天天看點

Spring靜态注入的三種方式:

Spring靜态注入的三種方式:

(說明:MongoFileOperationUtil是自己封裝的一個Mongodb檔案讀寫工具類,裡面需要依賴AdvancedDatastore對象執行個體,dsForRW用來擷取Mongodb資料源)

在springframework裡,我們不能@Autowired一個靜态變量,使之成為一個spring bean,例如下面這種方式:

[java] view plain copy

@Autowired  
private static AdvancedDatastore dsForRW;  

@Autowired
private static AdvancedDatastore dsForRW;
           

可以試一下,dsForRW在這種狀态下不能夠被依賴注入,會抛出運作時異常java.lang.NullPointerException,為什麼呢?靜态變量/類變量不是對象的屬性,而是一個類的屬性,spring則是基于對象層面上的依賴注入。

但是自己比較喜歡封裝工具類,并通過@Component注解成功能元件,但是功能元件中的方法一般都是靜态方法,靜态方法隻能調用靜态成員變量,于是就有了下面的問題。封有的時候封裝功能元件會需要底層的service注入,怎麼辦呢?

去網上搜了下解決辦法,簡單總結一下幾種實作方式;

1.xml方式實作;

[html] view plain copy

<bean id="mongoFileOperationUtil" class="com.*.*.MongoFileOperationUtil" init-method="init">  
    <property name="dsForRW" ref="dsForRW"/>  
</bean>  

<bean id="mongoFileOperationUtil" class="com.*.*.MongoFileOperationUtil" init-method="init">
    <property name="dsForRW" ref="dsForRW"/>
</bean>
           

[java] view plain copy

public class MongoFileOperationUtil {  

    private static AdvancedDatastore dsForRW;  

    private static MongoFileOperationUtil mongoFileOperationUtil;  

    public void init() {  
        mongoFileOperationUtil = this;  
        mongoFileOperationUtil.dsForRW = this.dsForRW;  
    }  

}  

public class MongoFileOperationUtil {

    private static AdvancedDatastore dsForRW;

    private static MongoFileOperationUtil mongoFileOperationUtil;

    public void init() {
        mongoFileOperationUtil = this;
        mongoFileOperationUtil.dsForRW = this.dsForRW;
    }

}
           

這種方式适合基于XML配置的WEB項目;

[email protected]方式實作;

[java] view plain copy

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;  
    }  

}  

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注解;

[java] view plain copy

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;  
    }  
}  

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注解;