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的值呢?
** 小結 **
繼承關系,在子bean中添加parent屬性,屬性值為父bean的id。同時父bean可以添加abstract屬性作為子bean的模版,變成抽象bean。
依賴關系。首先需要定義依賴的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 ,這兩個比較少用就不說了。
小結
使用bean的 scope 屬性來配置bean的作用域。
singleton:默認值。容器初始時創建bean實例,在這整個容器的聲明周期內只創建這一個bean
prototype:原型的。容器初始化不創建bean的實例。而在每次請求時都創建一個新的Bean實例,并返回。
session和request:少用。