关闭

Spring容器中Bean的作用域

标签: SpringBean作用域singleton作用域prototype作用域request作用域
456人阅读 评论(0) 收藏 举报
分类:

  当我们通过Spring容器创建一个Bean实例时,不仅可以完成该Bean的实例化,而且还可以指定该Bean的作用域,Spring支持的五种作用域如下:

singleton:单例模式,singleton作用域下的Bean将只产生一个实例,因此我们每次获取的实例都是同一实例。

prototype:每次通过getBean()方法获取Bean实例时,都会产生一个新的Bean实例,因此每次的实例都不同

request:用于Web应用,对于一次Http请求,request作用域内的Bean只生成一个Bean,也就是说同一次请求内,每次获取该Bean,

      获取的都是同一实例,但是如果到了下次请求(刷新页面)就会再次产生一个Bean实例,但是在每次的请求内多次获取

      Bean实例都是同一实例。

session:对于一次http会话,session作用域的Bean将只生成一个实例,仅在Web应用中该作用域才会真的有效。

global session:每个全局的HttpSession对应一个实例

如果不单独在配置文件中设置,默认的作用域为singleton作用域。

一:singleton作用域对比prototype作用域

1:配置文件beans.xml

        <!-- 配置一个默认的singleton Bean实例 -->
	<bean id="p1" class="com.mao.scope.Person"/>
	<!-- 配置一个prototype Bean实例 -->
	<bean id="p2" class="com.mao.scope.Person" scope="prototype"/>
	<!-- 配置一个默认的singleton Bean实例 -->
	<bean id="date" class="java.util.Date"/>

上面配置了两个默认的singleton Bean,一个prototype Bean。

Bean 实例是实现类Person就是一个最简单的java类,这里不再给出。

2:下面主程序测试BeanTest.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanTest {
	public static void main(String []args) throws InterruptedException{
		ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
		//singleton作用域  只生成一个实例 因此返回实例相同
		System.out.println(ctx.getBean("p1")==ctx.getBean("p1"));
		//prototype作用域 每次都会生成一个实例,因此返回的实例不同
		System.out.println(ctx.getBean("p2")==ctx.getBean("p2"));
		//线程虽然休眠了一秒,但是此作用域为singleton 所以在创建容器时date Bean就已经创建完了,属于一个实例
		//因此两次的输出时间相同
		System.out.println(ctx.getBean("date"));
		Thread.sleep(1000);
		System.out.println(ctx.getBean("date"));
	}
}

3:输出结果


  可以看出,singleton作用域的Bean,仅产生一个Bean实例,因此每次获取的实例时是同一Bean实例,但是prototype作用域的Bean实例,每次请求都会产生新的Bean实例,因此两次Bean实例并不相同,

值得注意的是,上面分两次获取了系统时间,虽然中间线程休眠了一秒,但是输出时间却相同,这是因为咱们在配置文件beans.xml定义的date Bean的时候是默认的singleton作用域,也就是说在创建Spring容器的时候,date Bean实例就已经创建出来了,虽然咱们获取了两次,但是singletype作用域仅仅产生一个实例,因此两次都是同一实例,所以输出的时间是相同的,但是如果我们将date Bean实例的作用域指定成scope="prototype",每次获取都会产生新的实例,再看结果:


这样就时间相差了一秒,这也说明了prototype作用域的Bean,每次获取的都是新创建的不同实例。

二:request作用域

request作用域仅对Web应用有效,因此需要在Web应用中需要额外配置。request作用域对于每次Http请求会产生一个实例,在同一次请求中获取的Bean实例是相同的。

1:新建Web项目

2:导入Jar文件

  将所有需要的Jar文件复制到项目WEB-INF\lib路径下,注意只能是此路径,Web应用默认在此路径加载Jar文件,而不是用户自定义的类库(java项目可以将Spring所需的jar放在用户自定义的路径下)。

3:修改Web配置文件Web.xml,添加如下:

<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<listener>
		<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>

4:创建spring配置文件applicationContext.xml  存放位置WEB-INF路径下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<!-- 创建Bean 并指定request作用域 -->
	<bean id="p" class="com.mao.requestScope.Person" scope="request"></bean>
	
</beans>

5:测试脚本 test.jsp 存放路径 WebContent路径下

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>
<%@ page import="org.springframework.web.context.*" %>
<%@ page import="org.springframework.web.context.support.*" %>
<%@ page import="com.mao.requestScope.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Spring Bean的作用域</title>
</head>
<body>
<%
// 获取Web应用初始化的Spring容器
WebApplicationContext ctx = 
	WebApplicationContextUtils.getWebApplicationContext(application);
// 两次获取容器中id为p的Bean
Person p1=(Person)ctx.getBean("p");
Person p2 = (Person)ctx.getBean("p");
out.println((p1 == p2) + "<br/>");
out.println(p1);
%>
</body>
</html>

6:运行结果


可以看出,request作用域内的Bean,每次访问都是同一实例,因此返回了true,但是如果我们刷新页面,再看结果


仔细对比两次结果,发现实例变了,这就说明,request作用域的Bean每次Http请求都会产生新的Bean实例,但是同一请求中访问Bean 都是同一实例,因此即使我们刷新页面,在这个请求下获取两次Bean实例,依然相同,返回了true。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:126581次
    • 积分:1909
    • 等级:
    • 排名:千里之外
    • 原创:66篇
    • 转载:28篇
    • 译文:0篇
    • 评论:9条
    文章分类
    最新评论