scope作用域
- scope作用域定義了spring容器中生成的bean實例的可見範圍,包括如下:
- singleton:生成唯一的bean實例,是spring裏的缺省作用域,spring容器初始化時進行實例化
- prototype:每次請求時,都會生成新的bean實例。建議:有狀態的bean使用prototype,無狀態使用singleton,故:spring容器初始化時,不會生成prototype實例
- request:針對每次的http請求,spring容器會創建一個全新的實例,只在當前的http請求生效
- session:針對某個httpsession,創建全新實例,只在當前session會話生效,不同的session之間的實例是隔離的
- global session
- 此外,還有自定義作用域
示例:
- 這裏只演示:singleton、prototype、自定義作用域三種
- 首先,創建一個maven工程(參照spring學習(一)中的方式)
- 其次:創建測試類:
package ioc3;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Fly {
public void say() {
System.out.println("I can fly");
}
}
class MyScope implements Scope {
private Map<String, Object> beanMap = new ConcurrentHashMap<String, Object>();
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
System.out.println("----------> self define myScope: " + name);
synchronized (this) {
if (!beanMap.containsKey(name)) {
System.out.println("----------> do not exist: " + name);
beanMap.put(name, objectFactory.getObject());
}
}
return beanMap.get(name);
}
@Override
public Object remove(String name) {
return beanMap.remove(name);
}
@Override
public void registerDestructionCallback(String name, Runnable callback) {
}
@Override
public Object resolveContextualObject(String key) {
return null;
}
@Override
public String getConversationId() {
return null;
}
}
<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="birdFlySingleTon" class="ioc3.Fly" scope="singleton"/>
<bean id="birdFlyProtoType" class="ioc3.Fly" scope="prototype"/>
<bean id="birdFlyMyScope" class="ioc3.Fly" scope="myScope"/>
</beans>
class Main {
public static void main(String[] args) {
ClassPathXmlApplicationContext beanFactory = new ClassPathXmlApplicationContext("ioc3-scope.xml");
beanFactory.getBeanFactory().registerScope("myScope", new MyScope());
System.out.println("========== 1. singleton模式 ==========");
Fly flySingleTon1 = beanFactory.getBean("birdFlySingleTon", Fly.class);
Fly flySingleTon2 = beanFactory.getBean("birdFlySingleTon", Fly.class);
System.out.println("多次請求時,bean實例是一樣的:flySingleTon1 == flySingleTon2 : " + (flySingleTon1 == flySingleTon2));
System.out.println("========== 2. prototype模式 ==========");
Fly flyProtoType1 = beanFactory.getBean("birdFlyProtoType", Fly.class);
Fly flyProtoType2 = beanFactory.getBean("birdFlyProtoType", Fly.class);
System.out.println("多次請求時,bean實例不一樣:flyProtoType1 == flyProtoType2 : " + (flyProtoType1 == flyProtoType2));
System.out.println("========== 3. 自定義scope ==========");
Fly flyMyScope1 = beanFactory.getBean("birdFlyMyScope", Fly.class);
Fly flyMyScope2 = beanFactory.getBean("birdFlyMyScope", Fly.class);
flyMyScope1.say();
flyMyScope2.say();
System.out.println("多次請求時,bean實例一樣(可以修改get方法變成不一樣):" +
"flyMyScope1 == flyMyScope2 : " + (flyMyScope1 == flyMyScope2));
}
}
========== 1. singleton模式 ==========
多次請求時,bean實例是一樣的:flySingleTon1 == flySingleTon2 : true
========== 2. prototype模式 ==========
多次請求時,bean實例不一樣:flyProtoType1 == flyProtoType2 : false
========== 3. 自定義scope ==========
----------> self define myScope: birdFlyMyScope
----------> do not exist: birdFlyMyScope
----------> self define myScope: birdFlyMyScope
I can fly
I can fly
多次請求時,bean實例一樣(可以修改get方法變成不一樣):flyMyScope1 == flyMyScope2 : true
- 結果說明
- 可以看到singleton確實唯一,而prototype每次都不一樣
- 自定義scope可以正常使用,並且運行