Bean的作用域
简单记录-Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)-Spring中的Bean
通过Spring容器创建一个Bean的实例时,不仅可以完成Bean的实例化,还可以为Bean指定特定的作用域。
那什么是Bean的作用域?Bena的作用域有什么用呢?
-
代理模式(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的时候,都会产生一个新的对象!
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
其余的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。
例如:
<bean id="scope" class="com.awen.scope.Scope" scope="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
com.awen.scope.Scope@74e52ef6
com.awen.scope.Scope@74e52ef6
true
true
Process finished with exit code 0
com.awen.scope.Scope@74e52ef6
com.awen.scope.Scope@74e52ef6
两次输出的结果相同,这说明Spring容器只创建了一个Scope类的实例。需要注意的是,如果不设置scope=“singleton”,其输出结果也是一个实例,因为Spring容器默认的作用域就是singleton。
prototype原型作用域
对需要保持会话状态的Bean(如Struts 2的Action类)应该使用prototype作用域。
在使用prototype作用域时,Spring容器会为每个对该Bean的请求都创建一个新的实例。
在Spring中如何配置prototype作用域?在Spring配置文件中,同样使用元素的scope属性,将Bean的作用域定义成prototype 。
例如
<bean id="scope" class="com.itheima.scope.Scope" scope=" 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
com.awen.scope.Scope@6f03482
com.awen.scope.Scope@9d5509a
false
false
Process finished with exit code 0
运行结果可以看到,
com.awen.scope.ScopeTest
com.awen.scope.Scope@6f03482
com.awen.scope.Scope@9d5509a
两次输出的Bean实例并不相同,这说明在prototype作用域下,创建了两个不同的Scope实例。