Spring Bean 的作用域

本文详细介绍了Spring框架中Bean的五种作用域:singleton、prototype、request、session和global-session,包括它们的定义、应用场景及如何在配置文件或注解中进行设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、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.youkuaiyun.com/feihong247/article/details/7798474

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值