您的位置:首页 > 编程语言 > Java开发

Spring Bean 的作用域

2016-03-16 09:58 603 查看
一、SpringFrameWork支持五种作用域(其中三种只能用在基于web的Spring ApplicationContext)。

内置支持的作用域分别如下:

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring bean