Spring-02

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

Bean和注入

定義兩個Bean如下所示:

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

public class Role {
    private String role_name;
}

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

xml主配置文件內(nèi)使用如下配置進行測試:

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

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

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

控制臺輸出:

  user [name=wukong, sex=男, role=role [role_name=斗戰(zhàn)勝佛]]

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

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

進行測試發(fā)現(xiàn)Junit報錯:

image.png

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

因此 我們在內(nèi)層的bean上設(shè)置id 其實沒有任何意義

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

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

存在這樣一種簡寫方式:

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

可以將上面配置聯(lián)系的代碼進行簡化書寫代碼

接口和注入

在開發(fā)當(dāng)中我們經(jīng)常會使用到接口 按照傳統(tǒng)的開發(fā)模式 現(xiàn)在我們有了新的包結(jié)構(gòu) 如下圖:

image.png

在正常的開發(fā)模式下 我們需要在接口的實現(xiàn)類下進行接口回調(diào) 如下圖


image.png

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

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

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

此時 我們可以直接通過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
后面的類路徑 需要書寫接口的類路徑 不是接口實現(xiàn)類(impl)的類路徑

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

構(gòu)造函數(shù)注入方式

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

我們更改User類里面的內(nèi)容 如下:

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

public User(){
    System.out.println("構(gòu)造方法");
}
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()方法
重新進行測試 結(jié)果如下:


image.png

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

現(xiàn)在我們添加一個有參的構(gòu)造函數(shù):

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

在xml配置文件內(nèi)添加如下代碼:

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

新建bean標(biāo)簽做注入 <constructor-arg>標(biāo)簽對應(yīng)類中的構(gòu)造函數(shù)
因為在User類中的有參構(gòu)造函數(shù)有兩個參數(shù) 所以<constructor-arg>標(biāo)簽要寫兩個 分別對應(yīng)兩個參數(shù) 并給予初始值

此時新建測試方法:

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

控制臺輸出:


image.png

產(chǎn)生 構(gòu)造方法 SetName 等結(jié)果
是因為我們同一個xml文件中配置了使用無參構(gòu)造函數(shù) 使用setter方式進行注入
xml文件一被加載 內(nèi)部所有的bean都會被進行實例化

別驚慌hhhh

值得注意的是 在 <constructor-arg>標(biāo)簽內(nèi)
存在index屬性 用來標(biāo)識形參的位置 起始值為1
存在type屬性 指明參數(shù)類型
如剛才我們對構(gòu)造函數(shù)進行的操作,完整內(nèi)容應(yīng)為如下:

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

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

    <constructor-arg name="role" ref="role" />
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,537評論 19 139
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,488評論 2 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,641評論 18 399
  • 文章作者:Tyan博客:noahsnail.com 3.4 依賴 標(biāo)準(zhǔn)企業(yè)應(yīng)用不會由一個對象(或Spring用語中...
    SnailTyan閱讀 1,265評論 0 1
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,011評論 0 11

友情鏈接更多精彩內(nèi)容