Spring(三)——Bean的 繼承關系、依賴關系、作用域

1、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">

    <bean id="ren1" class="test.Person">
        <property name="name" value="Hello World"></property>
        <property name="age" value="2333"></property>
    </bean>

    <bean id="ren2" class="test.Person" parent="ren1">
        <!-- <property name="name" value="Hello Spring"></property>
        <property name="age" value="666"></property> -->
    </bean>

</beans>
package test;

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

public class Main {

    public static void main(String[] args) {
        // 導入IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 獲取Person對象
        Person person1 = (Person) ctx.getBean("ren1");
        Person person2 = (Person) ctx.getBean("ren2");

        // 輸出Person
        System.out.println(person1);
        System.out.println(person2);
    }

}

ren2 的 bean 中是有一個 parent 的屬性的,這個屬性指向 ren1 bean,這說明 ren2 繼承了 ren1 的內容的。

但是如果在ren2有屬性值,那么將重寫該屬性值,類似于面向對象的重寫。


Spring允許繼承 bean 的配置,被繼承的 bean 成為父 bean,繼承這個父 bean 的bean 成為子 bean(這并非我們所說的父類和子類)。子 bean 可以覆蓋父 bean 的屬性。

這個繼承有什么用呢?首先可以省去重復的配置,你只需要繼承一個Bean就可以不需要配置那么多的屬性了。父bean作為模板,添加abstract屬性為true就行了,例如

<bean id="ren1" class="test.Person" abstract="true">
        <property name="name" value="Hello World"></property>
        <property name="age" value="2333"></property>
</bean>

這樣的話就不能創建ren1的實例,只用來被繼承。

如果一個bean沒有被指定class屬性,那么它必須是抽象bean,即 abstract=true。

2、Bean的依賴關系

Car.java

package test;

public class Car {

    private String brand;
    private String carID;

    public Car() {
        super();
    }

}

Person.java

package test;

public class Person {

    private String name;
    private int age;
    private Car car;

    public Person() {

    }

}

applicationContext.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">

    <bean id="che" class="test.Car">
        <property name="brand" value="Audi"></property>
        <property name="carID" value="123"></property>
    </bean>

    <bean id="ren" class="test.Person">
        <property name="name" value="Hello Spring"></property>
        <property name="age" value="666"></property>
        <property name="car" ref="che"></property>
    </bean>

</beans>

在這里,我們模擬的是每個人有一輛車,而車又是一個JavaBean,因此我們這里需要用到引用,即在property中不再是value屬性了而是ref

這里需要注意的是,如果沒有定義car的JavaBean那么就會報錯的。所以我們才說Person依賴于Car。這也很容易理解,我都沒寫id,怎么填寫ref的值呢?

** 小結 **

  1. 繼承關系,在子bean中添加parent屬性,屬性值為父bean的id。同時父bean可以添加abstract屬性作為子bean的模版,變成抽象bean。

  2. 依賴關系。首先需要定義依賴的bean(此例為Car),然后在被依賴bean(此例為Person)中的屬性值用ref取代value,并指向依賴bean的ID。

3、Bean的作用域

默認情況下,IOC容器,即那個xml文件只會為bean創建一個對象,這就是所說的單例類。每次調用這個bean的,容器只會返回同一個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">

    <bean id="che" class="test.Car">
        <property name="brand" value="Audi"></property>
        <property name="carID" value="123"></property>
    </bean>

</beans>
package test;

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

public class Main {

    public static void main(String[] args) {
        // 導入IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 獲取Person對象
        Car car1 = (Car) ctx.getBean("che");
        Car car2 = (Car) ctx.getBean("che");

        // 輸出Person
        System.out.println(car1 == car2);
    }

}

這里的輸出結果是 true 說明這兩個是同一個對象的。


修改配置文件:

<bean id="che" class="test.Car" scope="prototype">
  <property name="brand" value="Audi"></property>
  <property name="carID" value="123"></property>
</bean>

運行Mian.java可以看到輸出結果為false

我們看到scope的屬性,這里singleton當然就是這個屬性的默認值了,將 scope="prototype" 即原型。

原型是指:每次向容器中獲取bean對象,都會返回一個新的bean,即這兩個bean不是同一個對象。

我們同時發現這個 scope 的取值還有 session 和 request ,這兩個比較少用就不說了。

小結

  1. 使用bean的 scope 屬性來配置bean的作用域。

  2. singleton:默認值。容器初始時創建bean實例,在這整個容器的聲明周期內只創建這一個bean

  3. prototype:原型的。容器初始化不創建bean的實例。而在每次請求時都創建一個新的Bean實例,并返回。

  4. session和request:少用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容