Spring-02

注入自定義對象
上一篇文章說到了注入java內置對象的方法(Setter) 這次來說一說關于注入自定義類型對象的一些內容

Bean和注入

定義兩個Bean如下所示:

public class User {
    private String name;
    private String sex;
    private Role role;
}

public class Role {
    private String role_name;
}

兩個Bean里面都實現Get()和Set()方法 并且重寫toString()方法

xml主配置文件內使用如下配置進行測試:

<bean id="user" class="com.test.model.User">
    <property name="name" value="wukong" />
    <property name="sex" value="男" />
    <!-- 此時name所指代的屬性 不再是簡單的數據類型 而是自定義的對象 -->
    <!-- 再次使用bean標簽來進行實例化 -->
    <property name="role">
        <bean id="role" class="com.test.model.Role">
            <property name="role_name" value="斗戰勝佛" />
        </bean>
    </property>
</bean>

在測試文件內(使用Junit)編寫測試方法:

    @Test
    public void GetUserMessige(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        //User指代xml文件內的bean標簽的id
       //User.class指明User的類路徑 利用框架映射幫助我們進行實例化 
        User user= ac.getBean("user",User.class);
        System.out.println(user);
    }

控制臺輸出:

  user [name=wukong, sex=男, role=role [role_name=斗戰勝佛]]

但是這樣的寫法 會存在這樣一個大問題:
我們在xml文件內定義了兩個<bean> id分別為 user 和 role
但是我們只能獲取到id為user的bean內的內容,role我們獲取不到
進行如下測試:
xml配置文件內容保持上述不動 在Junit測試文件內新建測試方法 指向id為role的bean標簽

@Test
public void GetRoleMessige(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
    Role role= ac.getBean("role",Role.class);
    System.out.println(role);
}

進行測試發現Junit報錯:

image.png

報錯內容為 : No bean named 'role' available
沒有名為role的bean被定義
出現這個報錯的原因很好理解
==>
我們的確是定義了兩個bean
但是它們是包含與被包含的關系
role在user的內層 其作用范圍在uesr內
我們發出了想要越過user來直接獲取內層bean的請求
自然是獲取不到

因此 我們在內層的bean上設置id 其實沒有任何意義

綜上 我們還有第二種解決方案
我們將role的配置單獨書寫 并將兩個bean建立聯系
代碼如下:

  <bean id="user" class="com.test.model.User">
        <property name="name" value="wukong" />
        <property name="sex" value="男" />
        <property name="role">
            <!-- 使用<ref>標簽來使兩個獨立的bean建立聯系 -->
            <ref bean="role"/>
        </property>
    </bean>
    <bean id="role" class="com.test.model.Role">
        <property name="role_name" value="斗戰勝佛" />
    </bean>
</beans>

存在這樣一種簡寫方式:

  <property name="role" ref="role"/>
  <!--
        name="role"  指代類中的屬性
        ref="role"  指代獨立的bean的id值
  -->

可以將上面配置聯系的代碼進行簡化書寫代碼

接口和注入

在開發當中我們經常會使用到接口 按照傳統的開發模式 現在我們有了新的包結構 如下圖:

image.png

在正常的開發模式下 我們需要在接口的實現類下進行接口回調 如下圖


image.png

現在我們可以嘗試通過注入的方式來完成操作
在xml文件內聲明兩個實現類:

    <bean  id="userDaoImpl" class="com.test.dao.impl.UserDaoImpl"/>
    <bean  id="userServiceImpl" class="com.test.service.impl.UserServiceImpl">
            <!--  
                UserDaoImpl userdaoimpl = new UserDaoImpl();
                UserDao userDao = userdaoimpl;
              -->
           <property name="userdao" ref="userDaoImpl"></property>
    </bean>

可以看到 我們通過注入方式 利用框架幫助我們完成了接口回調的操作 具體實現邏輯 看上述代碼的注釋部分

此時 我們可以直接通過UsereService進行測試了:

@Test
public void 測試UserService(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
    UserService userService= ac.getBean("userServiceImpl",UserService.class);
    userService.Test01();
}

注意:
在書寫這段代碼的時候 ac.getBean("userServiceImpl",UserService.class);
雙引號括起來的地方 指向Service層bean的id
后面的類路徑 需要書寫接口的類路徑 不是接口實現類(impl)的類路徑

代碼提示:其實本段代碼 類似于上面所列出的User和Role的例子 不過是把實體bean轉換成了接口及其實現類 一點都不復雜 千萬別迷糊 hhhhh

構造函數注入方式

在前文 我們主要使用Setter注入方式 類中只有存在set方法才能夠使用
下面我們來測試另一種注入方式:構造函數注入

我們更改User類里面的內容 如下:

private String name;
private String sex;
private Role role;

public User(){
    System.out.println("構造方法");
}
public void setName( String name ) {
    System.out.println("setName");
    this.name = name;
}
public void setSex( String sex ) {
    System.out.println("setSex");
    this.sex = sex;
}
public void setRole( Role role ) {
    System.out.println("setRole");
    this.role = role;
}

然后重寫toString()方法
重新進行測試 結果如下:


image.png

可以看到具體的流程:
現在我們所寫的bean標簽的內容 是基于java默認為每一個類提供的無參的構造函數
每次加載bean標簽 都會首先去尋找所引用的類中的構造方法 然后通過公開的Set()方法 往實例化好的對象里面添加值
所以我們每個類當中 都要存在一個無參的構造方法來進行控制反轉

現在我們添加一個有參的構造函數:

public User( String name , String sex ) {
    super();
    this.name = name;
    this.sex = sex;
}

在xml配置文件內添加如下代碼:

    <bean id="user1" class="com.test.model.User">
        <constructor-arg name="name" value="八戒"/>
        <constructor-arg name="sex" value="男"/>
    </bean>

新建bean標簽做注入 <constructor-arg>標簽對應類中的構造函數
因為在User類中的有參構造函數有兩個參數 所以<constructor-arg>標簽要寫兩個 分別對應兩個參數 并給予初始值

此時新建測試方法:

@Test
public void 測試User構造函數(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
    User user= ac.getBean("user1",User.class);
    System.out.println(user);

控制臺輸出:


image.png

產生 構造方法 SetName 等結果
是因為我們同一個xml文件中配置了使用無參構造函數 使用setter方式進行注入
xml文件一被加載 內部所有的bean都會被進行實例化

別驚慌hhhh

值得注意的是 在 <constructor-arg>標簽內
存在index屬性 用來標識形參的位置 起始值為1
存在type屬性 指明參數類型
如剛才我們對構造函數進行的操作,完整內容應為如下:

    <bean id="user1" class="com.test.model.User">
        <constructor-arg name="name" index="0" type="java.lang.String" value="八戒"/>
        <constructor-arg name="sex" index="1" type="java.lang.String" value="男"/>
    </bean>

關于構造函數注入自定義類型 類似于下面的語句就可以完成:
指明類中屬性 指明引用的bean(我們在上文曾新建了一個專門用來實例化Role類型的bean)

    <constructor-arg name="role" ref="role" />
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,825評論 18 139
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,193評論 2 7
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,733評論 18 399
  • 文章作者:Tyan博客:noahsnail.com 3.4 依賴 標準企業應用不會由一個對象(或Spring用語中...
    SnailTyan閱讀 1,204評論 0 1
  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,830評論 0 11