2.2.2 泛型依賴注入

閱讀本篇需要讀者首先對(duì)Spring注解配置Bean部分的內(nèi)容有粗淺的了解
Spring注解配置Bean的兩種主要方式

Spring4開始可以為子類注入子類對(duì)應(yīng)的泛型類型成員變量的引用

在此通過一個(gè)實(shí)例來(lái)說明如何通過Spring的注解實(shí)現(xiàn)

  1. 主程序依賴于抽象類型
  2. 向子類所對(duì)應(yīng)的泛型類類型成員變量中注入其他對(duì)象的引用(此處為向UserService的成員變量中注入對(duì)UserRepository類型的對(duì)象的引用)



為了便于讀者理解品腹,先說點(diǎn)題外話岖食,討厭咬文嚼字的朋友可以選擇跳過,這里我所理解的依賴和注入舞吭,二者是分開的泡垃。依賴一方面只的是類型與類型之間的依賴關(guān)系析珊,另一方面是指最后主程序與主程序main方法中所使用的類之間的依賴關(guān)系。很明顯蔑穴,前者主要是抽象類AbstractService 對(duì) AbstractRepository的依賴關(guān)系忠寻,不過這個(gè)關(guān)系進(jìn)而被子類繼承成為UserService對(duì)UserRepository的依賴關(guān)系,為什么說這個(gè)依賴關(guān)系被繼承了呢存和?
很明顯奕剃,main()方法中本來(lái)只對(duì)UserService類的方法進(jìn)行了調(diào)用,但卻間接地調(diào)用了UserRepository的方法并得到了其方法的輸出結(jié)果捐腿,顯然調(diào)用前者方法的同時(shí)也調(diào)用了后者的方法纵朋,這表明UserService類對(duì)UserRepository類是有依賴關(guān)系的,而這依賴關(guān)系在這兩個(gè)類自己的代碼中沒有體現(xiàn)茄袖,很顯然是從父類型那繼承得到的
而主程序這邊很明顯操软,并沒有直接使用UserService類和UserRepository類的相關(guān)方法,而僅僅得到了AbstractService的對(duì)象也只調(diào)用了AbstractService的方法宪祥。所以我們的主程序是依賴于抽象類型的
另一點(diǎn)注入聂薪,指的就是資源的注入。我們是不可能直接創(chuàng)建兩個(gè)抽象類型的對(duì)象的蝗羊。
而我們的子類UserService中所使用的父類的成員變量repository它是AbstractRepository類型兼容的藏澳,但是很明顯它肯定不僅僅是AbstractRepository這個(gè)抽象類型。那它有時(shí)何時(shí)被創(chuàng)建何時(shí)又到我們所得到的這個(gè)UserService類的實(shí)例對(duì)象中來(lái)的呢耀找。答案就是我們Spring4開始才有的泛型依賴注入
后面配合代碼詳細(xì)介紹這個(gè)泛型依賴注入的過程


一.抽象類型

  • 抽象類型1:AbstractService
package thread.conor.spring.generic;
import org.springframework.beans.factory.annotation.Autowired;
public abstract class AbstractService <T>{
    @Autowired
    protected AbstractRepository<T> repository;
    public abstract void add(T t);
}
  • 抽象類型2:AbstractRepository
package thread.conor.spring.generic;
public abstract class AbstractRepository <T>{
    public abstract void act(T t);
}

注意:

  1. 由于AbstractService 中需要有一個(gè)repository成員變量來(lái)實(shí)現(xiàn)對(duì)另一個(gè)泛型類AbstractRepository的依賴關(guān)系笆载,所以不能使用接口代替抽象類
  2. 上面兩個(gè)抽象類都沒有使用與特定組件相關(guān)的注解(如@Component)也就意味著無(wú)法被Spring容器通過<context:component-scan>標(biāo)簽掃描到
  3. @Autowired注解標(biāo)識(shí)了repository成員變量依據(jù)類型AbstractRepository的自動(dòng)裝配


二. 實(shí)體類型

  1. UserService
package thread.conor.spring.generic;
import org.springframework.stereotype.Service;
import thread.conor.spring.domain.User;
@Service
public class UserService extends AbstractService<User>{
    @Override
    public void add(User user) {
        System.out.println("user " +user.getName() + " is in service");
        repository.act(user);
    }
}
  1. Repository
package thread.conor.spring.generic;

import org.springframework.stereotype.Repository;

import thread.conor.spring.domain.User;

@Repository
public class UserRepository extends AbstractRepository<User>{

    @Override
    public void act(User user) {
        System.out.println(user.getName()+" is added into repository");
    }
}
  1. user
package thread.conor.spring.domain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class User {
    private String name = "conor";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

注意:

  1. 上述實(shí)體類都有與組件相關(guān)的注解(@Repository,@Service,@Component),都會(huì)被Spring容器掃描到

三. 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"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <context:component-scan base-package="thread.conor.spring.generic,thread.conor.spring.domain"></context:component-scan>

</beans>

<context:component-scan base-package="thread.conor.spring.generic,thread.conor.spring.domain"></context:component-scan>此句即為配置需要掃描的包涯呻,其他外面的只是框子(套路)

四. Main主程序

package thread.conor.spring.generic;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-generic.xml");
        AbstractService service = (AbstractService) ctx.getBean("userService");
        service.add(ctx.getBean("user"));
    }
}

注意:

  1. 這里main方法只使用了抽象類型AbstractService,即除了IOC容器外只有對(duì)抽象類型AbstractService的依賴(對(duì)于AbstractRepository的依賴也是通過這層依賴進(jìn)行傳遞的)


五. 運(yùn)行結(jié)果

user conor is in service
conor is added into repository
  1. 第一句表明主程序雖然只對(duì)抽象類型AbstractService有依賴關(guān)系腻要,卻調(diào)用了其子類的方法复罐。
  2. 第二句說明在調(diào)用UserService的方法add(User user)時(shí)也通過其中的repository.act(user);這句話調(diào)用到了UserRepository的對(duì)象的方法act(User user)。這里repository是從UserService父類型AbstractService繼承而來(lái)的成員變量雄家,但是這個(gè)成員變量的引用指向的卻是UserRepository類的一個(gè)對(duì)象效诅,當(dāng)然這個(gè)對(duì)象是關(guān)于AbstractRepository類兼容的,這里這個(gè)repository成員變量就是通過AbstractService抽象類中對(duì)repository成員變量標(biāo)識(shí)的@Autowired注解來(lái)將 標(biāo)識(shí)了@Repository注解的UserRepository類 的對(duì)象依據(jù)類型自動(dòng)裝配到UserService的成員變量repository之中的
    這里UserService類的repository成員變量是從父類型繼承而來(lái)的趟济。

六. 此程序?qū)嵗囊蕾嚶彝叮^承關(guān)系如下圖所示:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市顷编,隨后出現(xiàn)的幾起案子戚炫,更是在濱河造成了極大的恐慌,老刑警劉巖媳纬,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件双肤,死亡現(xiàn)場(chǎng)離奇詭異施掏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)茅糜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門七芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蔑赘,你說我怎么就攤上這事狸驳。” “怎么了缩赛?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵耙箍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我峦筒,道長(zhǎng)究西,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任物喷,我火速辦了婚禮卤材,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘峦失。我一直安慰自己扇丛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布尉辑。 她就那樣靜靜地躺著帆精,像睡著了一般昔搂。 火紅的嫁衣襯著肌膚如雪翩概。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天晒哄,我揣著相機(jī)與錄音购啄,去河邊找鬼襟企。 笑死,一個(gè)胖子當(dāng)著我的面吹牛狮含,可吹牛的內(nèi)容都是我干的顽悼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼几迄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蔚龙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起映胁,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤木羹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后屿愚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汇跨,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡务荆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了穷遂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片函匕。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蚪黑,靈堂內(nèi)的尸體忽然破棺而出盅惜,到底是詐尸還是另有隱情,我是刑警寧澤忌穿,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布抒寂,位于F島的核電站,受9級(jí)特大地震影響掠剑,放射性物質(zhì)發(fā)生泄漏屈芜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一朴译、第九天 我趴在偏房一處隱蔽的房頂上張望井佑。 院中可真熱鬧,春花似錦眠寿、人聲如沸躬翁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盒发。三九已至,卻和暖如春狡逢,著一層夾襖步出監(jiān)牢的瞬間宁舰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工奢浑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留明吩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓殷费,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親低葫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子详羡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355