Spring容器中Bean的作用域

来源:互联网 发布:现货交易软件哪个好 编辑:程序博客网 时间:2024/05/17 08:50

当我们通过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

[html] view plain copy
  1.        <!-- 配置一个默认的singleton Bean实例 -->  
  2. <bean id="p1" class="com.mao.scope.Person"/>  
  3. <!-- 配置一个prototype Bean实例 -->  
  4. <bean id="p2" class="com.mao.scope.Person" scope="prototype"/>  
  5. <!-- 配置一个默认的singleton Bean实例 -->  
  6. <bean id="date" class="java.util.Date"/>  

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

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

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

[java] view plain copy
  1. import org.springframework.context.ApplicationContext;  
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  3.   
  4. public class BeanTest {  
  5.     public static void main(String []args) throws InterruptedException{  
  6.         ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");  
  7.         //singleton作用域  只生成一个实例 因此返回实例相同  
  8.         System.out.println(ctx.getBean("p1")==ctx.getBean("p1"));  
  9.         //prototype作用域 每次都会生成一个实例,因此返回的实例不同  
  10.         System.out.println(ctx.getBean("p2")==ctx.getBean("p2"));  
  11.         //线程虽然休眠了一秒,但是此作用域为singleton 所以在创建容器时date Bean就已经创建完了,属于一个实例  
  12.         //因此两次的输出时间相同  
  13.         System.out.println(ctx.getBean("date"));  
  14.         Thread.sleep(1000);  
  15.         System.out.println(ctx.getBean("date"));  
  16.     }  
  17. }  

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,添加如下:

[html] view plain copy
  1. <listener>  
  2.         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  3.     </listener>  
  4.   
  5.     <listener>  
  6.         <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>  
  7.     </listener>  

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

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">  
  6.     <!-- 创建Bean 并指定request作用域 -->  
  7.     <bean id="p" class="com.mao.requestScope.Person" scope="request"></bean>  
  8.       
  9. </beans>  

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

[javascript] view plain copy
  1. <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>  
  2. <%@ page import="org.springframework.web.context.*" %>  
  3. <%@ page import="org.springframework.web.context.support.*" %>  
  4. <%@ page import="com.mao.requestScope.*"%>  
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  6.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  7. <html xmlns="http://www.w3.org/1999/xhtml">  
  8. <head>  
  9.     <title>Spring Bean的作用域</title>  
  10. </head>  
  11. <body>  
  12. <%  
  13. // 获取Web应用初始化的Spring容器  
  14. WebApplicationContext ctx =   
  15.     WebApplicationContextUtils.getWebApplicationContext(application);  
  16. // 两次获取容器中id为p的Bean  
  17. Person p1=(Person)ctx.getBean("p");  
  18. Person p2 = (Person)ctx.getBean("p");  
  19. out.println((p1 == p2) + "<br/>");  
  20. out.println(p1);  
  21. %>  
  22. </body>  
  23. </html>  

6:运行结果


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


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

原创粉丝点击