1 前言
在 bean 標籤的 scope 屬性中可以選擇不同作用域,主要有 prototype、request、session、singleton,如下:
- prototype:每次從容器中調用 bean 時,都生成一個新的 bean
- request:每次 HTTP 請求,都會創建一個 bean,僅適用於 WebApplicationContext 環境
- session:同一個 HTTP Session 共享一個 bean,僅適用於 WebApplicationContext 環境
- singleton:spring IoC 容器僅存在一個 bean,以單例模式存在,scope 的默認值
本文僅介紹 singleton 和 prototype
待測試的 bean 所屬類爲 Student,如下:
Student.java
public class Student {
private Integer sid;
private String sname;
public Student() {
System.out.println("構造方法");
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
}
2 作用域爲 singleton
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="student" class="com.test.Student">
<property name="sid" value="1001"></property>
<property name="sname" value="張三"></property>
</bean>
</beans>
Test.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Student s1=ac.getBean("student",Student.class);
Student s2=ac.getBean("student",Student.class);
System.out.println(s1==s2);
}
}
運行結果:
構造方法
true
構造方法僅執行一次,並且 s1==s2 爲 true,說明容器中僅創建一個 bean。當 Test.java 只加載容器,不加載 bean 時,構造方法也會執行一次,即作用域爲 singleton(單例模式)時, bean 在容器加載的時候就已經創建。測試如下:
Test.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
}
}
運行結果:
構造方法
3 作用域爲 prototype
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="student" class="com.test.Student" scope="prototype">
<property name="sid" value="1001"></property>
<property name="sname" value="張三"></property>
</bean>
</beans>
Test.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Student s1=ac.getBean("student",Student.class);
Student s2=ac.getBean("student",Student.class);
System.out.println(s1==s2);
}
}
運行結果:
構造方法
構造方法
false
構造方法執行了2次,並且 s1==s2 爲 false,說明創建了2個 bean。另外,當只加載容器,不加載 bean 時,沒有輸出 “構造方法”,即作用域爲 prototype 時,bean 在加載 bean 的時候創建。