Spring 使用 setter 方法實(shí)現(xiàn)依賴注入的三種方式

本文討論最簡(jiǎn)單的 Spring setter 方法實(shí)現(xiàn)依賴注入的方法竟秫。
我們主要討論手動(dòng)模式的 setter 方法實(shí)現(xiàn)依賴注入荚孵,主要有三種模式货徙。

  • xml 資源配置元信息
  • Java 注解配置元信息
  • API 配置元信息

首先上代碼結(jié)構(gòu)圖:


在這里插入圖片描述

我們定義 model 類 Employee,兩個(gè)最簡(jiǎn)單屬性:String name 和 Long id挟鸠。
Boss 類繼承 Employee 類嘉赎,并且添加屬性 String title置媳。兩個(gè)類都加上 getter/ setter 方法和 toString() 方法。

我們首先定義基本的 dependency-injection-context.xml 文件公条,來(lái)定義 Employee 和 Boss 的 Spring bean拇囊。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--實(shí)時(shí)查找 bean 的方式-->
    <bean id="emp" class="container.overview.domain.Employee">
        <property name="id" value="1"></property>
        <property name="name" value="小明"></property>
    </bean>

    <bean id="boss" class="container.overview.domain.Boss" parent="emp" primary="true">
        <property name="title" value="CTO"></property>
    </bean>
</beans>

然后我們定義一個(gè) UserHolder 類來(lái)放置 Employee 類。

public class UserHolder {

    private Employee employee;

    public UserHolder(Employee employee) {
        this.employee = employee;
    }

    /*public UserHolder() {

    }*/

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    @Override
    public String toString() {
        return "UserHolder{" +
                "employee=" + employee +
                '}';
    }
}

xml 資源配置元信息

相關(guān) xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <import resource="classpath:/META-INF/dependency-injection-context.xml"/>

    <bean class="ioc.dependency.injection.UserHolder">
        <property name="employee" ref="boss"/>
    </bean>

</beans>

我們第一個(gè)最簡(jiǎn)單的方式就是使用 xml 來(lái)實(shí)現(xiàn)依賴注入靶橱。如上面的 xml 文件所示寥袭,我們的 UserHolder 類的 <property name="employee" ref="boss"/>

Java 代碼:

public class XmlDependencyInjectionDemo {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); // 這個(gè)類可以實(shí)現(xiàn)層次性关霸、集合類型传黄、單一類型的
        // 查找。
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        String resourcePath = "classpath:/META-INF/dependency-setter-injection.xml";
        // 加載 xml 資源谒拴,解析并且生成 BeanDefinition
        xmlBeanDefinitionReader.loadBeanDefinitions(resourcePath);
        UserHolder userHolder = beanFactory.getBean(UserHolder.class);
        System.out.println(userHolder);
    }
}

Java 注解配置元信息

public class AnnotationDependencyInjectionDemo {
    public static void main(String[] args) {
        // 創(chuàng)建 beanFactory 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 注冊(cè)配置類來(lái)取代我們的 xml 文件。
        applicationContext.register(AnnotationDependencyInjectionDemo.class);
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        String resourceLocation = "META-INF/dependency-injection-context.xml";
        // 加載 xml 資源涉波,解析并且生產(chǎn) beanDefinition
        xmlBeanDefinitionReader.loadBeanDefinitions(resourceLocation);
        applicationContext.refresh();
        UserHolder holder = applicationContext.getBean(UserHolder.class);
        System.out.println(holder);
        applicationContext.close();
    }

    @Bean
    public UserHolder userHolder(Employee employee) {
        return new UserHolder(employee);
    }
}

將當(dāng)前類作為配置類英上,然后使用 @Bean 注解注入 Spring bean。

API 配置元信息

public class APIDependencyInjectionDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 生成并且注冊(cè) UserHolder 的 beanDefinition
        BeanDefinition beanDefinition = createDefinition();
        applicationContext.registerBeanDefinition("userHolder",beanDefinition);
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        String resourceLocation = "META-INF/dependency-injection-context.xml";
        xmlBeanDefinitionReader.loadBeanDefinitions(resourceLocation);
        // 啟動(dòng)應(yīng)用上下文
        applicationContext.refresh();
        UserHolder userHolder = applicationContext.getBean(UserHolder.class);
        System.out.println(userHolder);
        applicationContext.close();
    }

    private static BeanDefinition createDefinition() {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserHolder.class);
        beanDefinitionBuilder.addPropertyReference("employee","boss");
        return beanDefinitionBuilder.getBeanDefinition();

    }
}

使用相關(guān)的 API 來(lái)實(shí)現(xiàn) setter 注入依賴啤覆。


完整代碼放在我的 github 上苍日。戳此可以查看

本文參考資料:小馬哥講Spring核心編程思想
自動(dòng)注入可以參考我的另一篇文章 自動(dòng)注入 autowire 中 byName 和 byType 的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窗声,隨后出現(xiàn)的幾起案子相恃,更是在濱河造成了極大的恐慌,老刑警劉巖笨觅,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拦耐,死亡現(xiàn)場(chǎng)離奇詭異耕腾,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杀糯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門扫俺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人固翰,你說(shuō)我怎么就攤上這事狼纬。” “怎么了骂际?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵疗琉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我歉铝,道長(zhǎng)盈简,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任犯戏,我火速辦了婚禮送火,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘先匪。我一直安慰自己种吸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布呀非。 她就那樣靜靜地躺著坚俗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪岸裙。 梳的紋絲不亂的頭發(fā)上猖败,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音降允,去河邊找鬼恩闻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛剧董,可吹牛的內(nèi)容都是我干的幢尚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼翅楼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尉剩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起毅臊,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤理茎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皂林,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朗鸠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了式撼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片童社。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖著隆,靈堂內(nèi)的尸體忽然破棺而出扰楼,到底是詐尸還是另有隱情,我是刑警寧澤美浦,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布弦赖,位于F島的核電站,受9級(jí)特大地震影響浦辨,放射性物質(zhì)發(fā)生泄漏蹬竖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一流酬、第九天 我趴在偏房一處隱蔽的房頂上張望币厕。 院中可真熱鬧,春花似錦芽腾、人聲如沸旦装。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阴绢。三九已至,卻和暖如春艰躺,著一層夾襖步出監(jiān)牢的瞬間呻袭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工腺兴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留左电,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓页响,卻偏偏與公主長(zhǎng)得像篓足,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拘泞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359