Spring Bean 的作用域
2016-03-16 09:58
603 查看
一、SpringFrameWork支持五种作用域(其中三种只能用在基于web的Spring ApplicationContext)。
protorype:与singleton相反,这个范围为每一个bean请求创建一个实例,即为每一个用到的地方都会创建一个 bean 实例。
request:在一次HTTP请求中,一个 bean 定义对应一个实例,即每次HTTP请求时都会有各自的bean实例。在请求完成以后,bean会失效并被垃圾回收器回收,该作用域仅在基于 web 的Spring ApplicationContext 情形下有效。
Session:确保每个HTTP Session中有一个 bean 的实例,在session 过期后,bean会随之失效并且被垃圾回收器回收。 该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
global-sesson:在全局的 HTTP Session中,一个bean只有一个实例。仅在使用 Portlet的时候有效,该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
用注解定义:
当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。
请注意Spring的singleton bean概念与GoF模式一书中定义的Singleton模式是完全不同的。经典的GoF Singleton模式中所谓的对象范围是指在每一个ClassLoader 中 指定class创建的实例有且仅有一个 。把Spring的singleton作用域描述成一个container (容器)对应一个bean 实例最为贴切。也就是说假如在单个Spring容器内定义了某个指定class的bean,那么Spring容器将会创建一个并且仅有一个 由该bean定义指定的类实例。Singleton作用域是Spring中的缺省作用域 。要在XML中将bean定义成singleton,可以这样
beans.xml配置文件中配置如下所示:
测试代码如下所示:
运行测试程序,结果输出为: true .说明是只创建了一个PersonServiceBean.
2、 Prototype作用域
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会创建一个新的bean实例 。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
下图演示了Spring的prototype作用域。请注意,通常情况下,DAO不会被配置成prototype,因为DAO通常不会持有任何会话状态,因此应该使用singleton作用域。
在XML中将bean定义成prototype,可以这样配置:
将beans.xml配置文件中的配置信息改为如下所示:
再运行上面的测试程序,输出结果为: false ,说明创建了两个PersonServiceBean.
其他作用域,即request、session以及global session 仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架)。这些作用域仅仅在使用基于web的Spring ApplicationContext实现(如XmlWebApplicationContext)时有用。 如果在普通的Spring IoC容器中,比如像XmlBeanFactory或ClassPathXmlApplicationContext, 尝试使用这些作用域,你将会得到一个IllegalStateException异常(未知的bean作用域)。
参考文章:
http://blog.csdn.net/feihong247/article/details/7798474
内置支持的作用域分别如下:
singleton:这是bean的默认范围,这个范围不管有多少个请求,每个容器中只有一个bean实例,单例模式由 bean factory自身来维护。protorype:与singleton相反,这个范围为每一个bean请求创建一个实例,即为每一个用到的地方都会创建一个 bean 实例。
request:在一次HTTP请求中,一个 bean 定义对应一个实例,即每次HTTP请求时都会有各自的bean实例。在请求完成以后,bean会失效并被垃圾回收器回收,该作用域仅在基于 web 的Spring ApplicationContext 情形下有效。
Session:确保每个HTTP Session中有一个 bean 的实例,在session 过期后,bean会随之失效并且被垃圾回收器回收。 该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
global-sesson:在全局的 HTTP Session中,一个bean只有一个实例。仅在使用 Portlet的时候有效,该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
怎样定义 bean 的作用域?
在配置文件中定义:<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-2.5.xsd"> <bean id="demoBean" class="com.howtodoinjava.application.web.DemoBean" scope="session" /> </beans>
用注解定义:
@Service @Scope("session") public class DemoBean { //Some code }
实例验证:
1.Singleton作用域当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。
请注意Spring的singleton bean概念与GoF模式一书中定义的Singleton模式是完全不同的。经典的GoF Singleton模式中所谓的对象范围是指在每一个ClassLoader 中 指定class创建的实例有且仅有一个 。把Spring的singleton作用域描述成一个container (容器)对应一个bean 实例最为贴切。也就是说假如在单个Spring容器内定义了某个指定class的bean,那么Spring容器将会创建一个并且仅有一个 由该bean定义指定的类实例。Singleton作用域是Spring中的缺省作用域 。要在XML中将bean定义成singleton,可以这样
<!-- the following is equivalent, though redundant (singleton scope is the default); using spring-beans-2.0.dtd or upper--> <bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/> <!-- the following is equivalent and preserved for backward compatibility in spring-beans.dtd --> <bean id="accountService" class="com.foo.DefaultAccountService" singleton="true"/> 测试:
beans.xml配置文件中配置如下所示:
<bean id="personService" class="examples.test.PersonServiceBean" ></bean>
测试代码如下所示:
public class SpringTest { @Test public void instanceSpring(){ ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService1 = (PersonService)ctx.getBean("personService"); PersonService personService2 = (PersonService)ctx.getBean("personService"); System.out.println(personService1==personService2); } }
运行测试程序,结果输出为: true .说明是只创建了一个PersonServiceBean.
2、 Prototype作用域
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会创建一个新的bean实例 。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
下图演示了Spring的prototype作用域。请注意,通常情况下,DAO不会被配置成prototype,因为DAO通常不会持有任何会话状态,因此应该使用singleton作用域。
在XML中将bean定义成prototype,可以这样配置:
<!-- using spring-beans-2.0.dtd or upper --> <bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/> <!-- the following is equivalent and preserved for backward compatibility in spring-beans.dtd --> <bean id="accountService" class="com.foo.DefaultAccountService" singleton="false"/>
将beans.xml配置文件中的配置信息改为如下所示:
<bean id="personService" class="cn.itcast.service.impl.PersonServiceBean" scope="prototype"></bean>
再运行上面的测试程序,输出结果为: false ,说明创建了两个PersonServiceBean.
其他作用域,即request、session以及global session 仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架)。这些作用域仅仅在使用基于web的Spring ApplicationContext实现(如XmlWebApplicationContext)时有用。 如果在普通的Spring IoC容器中,比如像XmlBeanFactory或ClassPathXmlApplicationContext, 尝试使用这些作用域,你将会得到一个IllegalStateException异常(未知的bean作用域)。
参考文章:
http://blog.csdn.net/feihong247/article/details/7798474
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- Spring Bean基本管理实例详解
- java实现简单美女拼图游戏
- 详解Java的Spring框架中的事务管理方式
- 解析Java的Spring框架的BeanPostProcessor发布处理器
- Java开发框架spring实现自定义缓存标签
- java基本教程之线程休眠 java多线程教程
- JSP开发中在spring mvc项目中实现登录账号单浏览器登录