天天看點

【Spring】Spring中的Bean - 3、Bean的作用域Bean的作用域

Bean的作用域

簡單記錄-Java EE企業級應用開發教程(Spring+Spring MVC+MyBatis)-Spring中的Bean

通過Spring容器建立一個Bean的執行個體時,不僅可以完成Bean的執行個體化,還可以為Bean指定特定的作用域。

那什麼是Bean的作用域?Bena的作用域有什麼用呢?

官網:https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-factory-scopes

【Spring】Spring中的Bean - 3、Bean的作用域Bean的作用域
  1. 代理模式(Spring預設機制):get到的都是同一個對象!
    <bean id="accountService" class="com.something.DefaultAccountService"/>
    
    <!-- the following is equivalent, though redundant (singleton scope is the default) -->
    <bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
               
  2. 原型模式:每次從容器中get的時候,都會産生一個新的對象!
  3. 其餘的request、session、application、這些個隻能在web開發中使用。

作用域的種類

Spring 為Bean的執行個體定義了7種作用域,如下表所示:

【Spring】Spring中的Bean - 3、Bean的作用域Bean的作用域

注意:在上表7種作用域中,singleton和prototype是最常用的兩種作用域。

【Spring】Spring中的Bean - 3、Bean的作用域Bean的作用域

這裡隻有六種哦 singleton、prototype、request、session、application和websocket

沒了globalSession的

singleton單例作用域和prototype原型作用域。

singleton單例作用域

​ singleton是Spring容器預設的作用域,當Bean的作用域為singleton時,Spring容器就隻會存在一個共享的Bean執行個體。

singleton作用域對于無會話狀态的Bean(如Dao 元件、Service元件)來說,是最理想的選擇。

在Spring配置檔案中,Bean的作用域是通過元素的scope屬性來指定的,該屬性值可以設定為singleton、prototype、request、session、globalSession、application和websocket七個值,分别表示Bean的七種作用域。

在Spring中如何配置singleton作用域? 在Spring配置檔案中,可以使用元素的scope屬性,将Bean的作用域定義成singleton。

例如:

小案例來了解一下singleton作用域吧。

在項目chapter02中,建立一個com.awen.scope包,在包中建立Scope類,該類不需要寫任何方法。

package com.awen.scope;
public class Scope  {

}

           

在src/main/resources目錄下,建立一個配置檔案beans4.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="scope" class="com.awen.scope.Scope" scope="singleton"/> 
<!--	<bean id="scope" class="com.awen.scope.Scope" scope="prototype" />-->
</beans>
           

最後在com.awen.scope包中建立測試類ScopeTest,來測試singleton作用域,編輯後如檔案所示。檔案ScopeTest.java

package com.awen.scope;
import org.springframework.context.ApplicationContext;
import 
	org.springframework.context.support.ClassPathXmlApplicationContext;
public class ScopeTest {
	public static void main(String[] args) {
		
		// 加載配置檔案

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans4.xml");
		// 輸出獲得執行個體
		System.out.println(applicationContext.getBean("scope"));
		System.out.println(applicationContext.getBean("scope"));
		System.out.println(applicationContext.getBean("scope") == applicationContext.getBean("scope")  );

		Scope scope = (Scope)applicationContext.getBean("scope");
		Scope scope2= (Scope) applicationContext.getBean("scope");
		System.out.println(scope == scope2);
	}
}

           

執行程式後,控制台的輸出結果如下所示。

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=1119:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.scope.ScopeTest
[email protected]
[email protected]
true
true

Process finished with exit code 0

           

[email protected]

[email protected]

兩次輸出的結果相同,這說明Spring容器隻建立了一個Scope類的執行個體。需要注意的是,如果不設定scope=“singleton”,其輸出結果也是一個執行個體,因為Spring容器預設的作用域就是singleton。

prototype原型作用域

​ 對需要保持會話狀态的Bean(如Struts 2的Action類)應該使用prototype作用域。

在使用prototype作用域時,Spring容器會為每個對該Bean的請求都建立一個新的執行個體。

在Spring中如何配置prototype作用域?在Spring配置檔案中,同樣使用元素的scope屬性,将Bean的作用域定義成prototype 。

例如

原型作用域

beans4.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="scope" class="com.awen.scope.Scope" scope="singleton"/>-->
	<bean id="scope" class="com.awen.scope.Scope" scope="prototype" />
</beans>
           

運作結果

D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=1185:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\JavaEE-enterprise-application-development-tutorial\chapter02\target\classes;D:\Environments\apache-maven-3.6.2\maven-repo\javax\annotation\jsr250-api\1.0\jsr250-api-1.0.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-webmvc\5.2.3.RELEASE\spring-webmvc-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-aop\5.2.3.RELEASE\spring-aop-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-beans\5.2.3.RELEASE\spring-beans-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-context\5.2.3.RELEASE\spring-context-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-core\5.2.3.RELEASE\spring-core-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-jcl\5.2.3.RELEASE\spring-jcl-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-expression\5.2.3.RELEASE\spring-expression-5.2.3.RELEASE.jar;D:\Environments\apache-maven-3.6.2\maven-repo\org\springframework\spring-web\5.2.3.RELEASE\spring-web-5.2.3.RELEASE.jar com.awen.scope.ScopeTest
[email protected]
[email protected]
false
false

Process finished with exit code 0

           

運作結果可以看到,

com.awen.scope.ScopeTest

[email protected]

[email protected]

兩次輸出的Bean執行個體并不相同,這說明在prototype作用域下,建立了兩個不同的Scope執行個體。