1. 程式人生 > >Spring 的單例模式和多例模式

Spring 的單例模式和多例模式

在Spring中,Bean的scope屬性中存在著兩種模式既單例模式(singleton)和多例模式(prototype)。

        singleton 單例模式: 物件在整個系統中只有一份,所有的請求都用一個物件來處理,如service和dao層的物件一般是單例的。

                                        為什麼使用單例:因為沒有必要每個請求都新建一個物件的時候,因為這樣會浪費CPU和記憶體。

        prototype 多例模式:物件在整個系統中可以有多個例項,每個請求用一個新的物件來處理,如action。

                                        為什麼使用多例:防止併發問題;即一個請求改變了物件的狀態,此時物件又處理另一個請求,而之前請求對物件的狀態改變導致了物件對另一個請求做了錯誤的處理;

 Spring bean 預設的是單例模式。

例項:我們先建立一個User類,類有id,name,password三個私有成員變數,生成他們的get和set方法。

package a_helloword.entity;

public class User {
    private String id;
    private String name;
    private String password;


    public void destroy(){
        System.out.println("我銷燬了");
    }
    public void init(){
        //this.name="給不";
        System.out.println("已經呼叫了初始化方法");
    }
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password1) {
        this.password = password1;
    }

}

接下來在src下建立一個applicationContext.xml檔案,該檔案是用來配置Spring的

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
							http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
							http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
							http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd ">
    <!--把User類放到容器中-->
    <!--
        bean:該元素需要Spring來管理,將User物件交給Spring管理
        name: 給被管理的物件取一個名字,為了更方便的根據名字獲得物件,用name的時候不能用特殊字元
        id:和name的作用是一樣的,使用name的話不能使用特殊字元。儘量使用name,
        class:完整類名
        scope: singleton:單例,prototype :多例
        init-method:建立完成物件後,立即執行的方法
        destroy-method:物件消亡的時候呼叫,Spring 容器關閉時會銷燬所有的物件
    -->
    <bean  id="user"
           name="user"
           class="a_helloword.entity.User"
           scope="singleton"
           init-method="init"
           destroy-method="destroy"
    ></bean>


</beans>

接下來寫一個測試類Demo 用來測試單例和多例模式的

package a_helloword.test;

import a_helloword.entity.User;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo {
    @Test
    public void fun(){
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("a_helloword/applicationContext.xml");
        User user = (User) ac.getBean("user");
        User user1 = (User) ac.getBean("user");
       System.out.println(user);
       System.out.println(user1);
        //ac.close();
    }
}

單例模式執行結果

已經呼叫了初始化方法
[email protected]30f
[email protected]

將配置檔案中的singleton替換為prototype

多例模式的執行結果

已經呼叫了初始化方法
已經呼叫了初始化方法
[email protected]
[email protected]
總結:從例項結果看出單例模式的輸出結果指向同一個物件,而多例的指向了不同的物件,說明多例的從新建立了一個物件。