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預設機制):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"/>
- 原型模式:每次從容器中get的時候,都會産生一個新的對象!
- 其餘的request、session、application、這些個隻能在web開發中使用。
作用域的種類
Spring 為Bean的執行個體定義了7種作用域,如下表所示:
注意:在上表7種作用域中,singleton和prototype是最常用的兩種作用域。
這裡隻有六種哦 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執行個體。