【spring】Bean對象值注入

一、設值注入

設值注入是指,通過 setter 方法傳入被調用者的實例。這種注入方式簡單、直觀,因而在 Spring 的依賴注入中大量使用。

構建兩個Bean:

public class School {
    private String name;

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

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class Student {
    private String username;
    private String password;
    private School school;

    public void setSchool(School school) {
        this.school = school;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", school=" + school +
                '}';
    }
}
<?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">
    <bean id="school" class="cn.lwb.spring.setterInject.School">
        <property name="name" value="sichuan"/>
    </bean>

    <bean id="student" class="cn.lwb.spring.setterInject.Student">
        <property name="username" value="lwb" />
        <property name="password" value="520" />
        <property name="school" ref="school"/>
    </bean>

</beans>
    @org.junit.Test
    public void test1() {
        String config = "cn/lwb/spring/setterInject/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(config);
        Student student = (Student) applicationContext.getBean("student");
        System.out.println(student);
    }

輸出結果:

當指定 bean 的某屬性值爲另一 bean 的實例時,通過 ref 指定它們間的引用關係。 ref的值必須爲某 bean 的 id 值。

二、構造注入

構造注入是指,在構造調用者實例的同時,完成被調用者的實例化。即,使用構造器設置依賴關係。

public Student(String username, String password, School school) {
        this.username = username;
        this.password = password;
        this.school = school;
    }
    <!--構造器注入,索引注入-->
    <bean id="student1" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg index="0" value="lwb"/>
        <constructor-arg index="1" value="520" />
        <constructor-arg index="2" ref="school"/>
    </bean>

    <!--注入順序必須與構造器中參數的順序一致-->
    <bean id="student2" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg value="lwb"/>
        <constructor-arg value="520" />
        <constructor-arg ref="school"/>
    </bean>

    <!--根據構造器參數名稱注入-->
    <bean id="student3" class="cn.lwb.spring.setterInject.Student">
        <constructor-arg name="username" value="lwb"/>
        <constructor-arg name="password" value="520" />
        <constructor-arg name="school" ref="school"/>
    </bean>

三、命名空間注入

對於設值注入與構造注入,在配置文件中,除了使用<property/>或<constructor-arg/>標籤外,還可使用命名空間注入的方式,讓注入的以<bean/>標籤屬性的方式出現。根據注入實現方式的不同,分爲 p 命名空間注入與 c 命名空間注入。
p 命名空間注入:採用設值注入方式,故需要有相應的 setter
c 命名空間注入:採用構造注入方式,故需要有相應的構造器

  1. p 命名空間設值注入

p命名空間設值注入,引入命名空間約束:xmlns:p="http://www.springframework.org/schema/p",在文檔中搜索p:name,便可以找到文檔例子

2. C命名空間構造注入

依然在文檔中搜索,可以找到例子:

四、集合屬性注入

<?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:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

        <bean id="school1" class="cn.lwb.spring.connectionInject.School" p:name="清華大學"/>
        <bean id="school2" class="cn.lwb.spring.connectionInject.School" p:name="北京大學"/>

        <bean id="student" class="cn.lwb.spring.connectionInject.Student">
            <property name="myMap">
                <map>
                    <entry key="張三" value="18"/>
                    <entry key="李四" value="18"/>
                    <entry key="王五" value="18"/>
                </map>
            </property>
            <property name="myList">
                <list>
                    <ref bean="school1"/>
                    <ref bean="school2"/>
                </list>
            </property>
            <property name="myPro">
                <props>
                    <prop key="name">lwb</prop>
                    <prop key="age">18</prop>
                </props>
            </property>
            <property name="mySet">
                <set>
                    <value>清華</value>
                    <value>北大</value>
                </set>
            </property>
            <property name="myStrs">
                <array>
                    <value>中國</value>
                    <value>四川</value>
                    <value>成都</value>
                </array>
            </property>
        </bean>
</beans>

其中值爲簡單屬性的Set/List/Array可以用簡寫的方式:

<property name="mySet" value="清華,北大" />
<property name="myStrs" value="中國,四川,成都" />

五、對於域屬性的自動注入

對於域屬性的注入,也可不在配置文件中顯示的注入。可以通過爲<bean/>標籤設置autowire 屬性值,爲域屬性進行隱式自動注入。根據自動注入判斷標準的不同,可以分爲兩種:

byName:根據名稱自動注入
byType:根據類型自動注入
1、byName 方式自動注入

當配置文件中被調用者 Bean 的 id 值與代碼中調用者 Bean 類的屬性名相同時,可使用byName 方式,讓容器自動將被調用者 Bean 注入給調用者 Bean。容器是通過調用者的 Bean類的屬性名與配置文件的被調用者 bean 的 id 進行比較而實現自動注入的。


2、byType 方式自動注入

使用 byType 方式自動注入,要求:配置文件中被調用者 bean 的 class 屬性指定的類,要與代碼中調用者 Bean 類的某域屬性類型同源。即要麼相同,要麼有 is-a 關係(子類,或是實現類)。但這樣的同源的被調用 bean 只能有一個。多於一個,容器就不知該匹配哪一個了。

六、SPEL

spring可以通過SPEL表達式來注入值,同時也可以使用一個Bean調用另一個Bean的方法來注入值:

public class Person {

    private String pusernmae;
    private int page;

    public String getPusernmae() {
        return pusernmae;
    }

    public void setPusernmae(String pusernmae) {
        this.pusernmae = pusernmae;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    @Override
    public String toString() {
        return "Person{" +
                "pusernmae='" + pusernmae + '\'' +
                ", page='" + page + '\'' +
                '}';
    }

    public int getAge() {
        return page > 20 ? 20 : page;
    }
}
public class Student {

    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
    <bean id="person" class="cn.lwb.spring.SPEL.Person">
        <property name="page" value="#{T(java.lang.Math).random() * 50}" />
        <property name="pusernmae" value="張三" />
    </bean>

    <bean id="student" class="cn.lwb.spring.SPEL.Student">
        <property name="username" value="王五" />
        <!--<property name="age" value="#{person.page > 25 ? 20 : person.page}"/>-->
        <property name="age" value="#{person.getAge()}"/>
    </bean>

由上面的xml配置可以看見,SPEL既可以通過java函數表達式來注入值,也可以通過調用別的Bean的方法或者屬性來給自己注入值。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章