spring學習-IOC(六)-scope作用域

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");
    }
}

/**
 * 通過實現:org.springframework.beans.factory.config.Scope實現自定義Scope的方式
 * 實現樣例,參見:org.springframework.context.support.SimpleThreadScope
 * 網上樣例:https://blog.csdn.net/elim168/article/details/75581670
 */
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">

    <!--1 singleton模式-->
    <bean id="birdFlySingleTon" class="ioc3.Fly" scope="singleton"/>

    <!--2 prototype模式-->
    <bean id="birdFlyProtoType" class="ioc3.Fly" scope="prototype"/>

    <!--3 自定義scope模式-->
    <bean id="birdFlyMyScope" class="ioc3.Fly" scope="myScope"/>

</beans>
  • 創建測試方法:

class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext beanFactory = new ClassPathXmlApplicationContext("ioc3-scope.xml");
        // 開始註冊自己的bean
        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可以正常使用,並且運行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章