Bean的作用域就是值Bean实例的生存空间或有效范围,Spring为Bean实例定义了多种来满足不同情况下的应用需求,如下所示。
- singleton:在每个Spring IoC容器中,一个Bean定义对应一个对象实例。
- prototype:一个bean定义对应多个对象实例。
- request:在一次Http请求中,容器会返回该Bean的同一个实例,而对于不同的用户请求,会返回不同的实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
- session:再一次HTTP Session中,容器会返回该Bean的同一个实例。而对于不同的HTTP Session请求,会返回不同的实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
- global session:在一个全局的HTTP Session中,容器会返回该Bean的同一个实例。仅在使用portlet context时有效。
1.singleton(单实例)作用域
这是Spring容器默认的作用域,当一个Bean的作用域为singleton时,Spring IoC容器中指挥存在一个共享的Bean实例,并且所有对Bean的请求,只要id与该Bean定义相匹配,就只会返回Bean的同一个实例。
要在Spring配置文件applicationContext.xml中将Bean定于成singleton,可以这样配置:
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
<bean id="helloSpring" class="com.ssm.HelloSpring" scope="singleton">
<property name="userName" value="张三"></property>
</bean>
</beans>
创建测试类TestBeanScope,在main()方法中测试singleton作用域,代码如下:
package com.ssm;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestBeanScope {
public static void main(String[] args) {
//加载applicationContext.xml配置
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取配置中的实现
HelloSpring hs1 = (HelloSpring)context.getBean("helloSpring");
HelloSpring hs2 = (HelloSpring)context.getBean("helloSpring");
System.out.println(hs1 == hs2);
}
}
运行测试类TestBeanScope,控制台输出结果为true,说明hs1和hs2的地址时相等的,由此可见在单实例作用域下,只创建了一个HelloSpring类的实例。
2.prototype(原型模式)作用域
prototype作用域的Bean在每次对该Bean请求时都会创建一个新的Bean实例,对需要保持会话状态的Bean应该使用prototype作用域。Spring不能对一个原型模式Bean的整个声明周期负责,容器在初始化、装配好一个原型模式实例后,将它交给客户端,就不再过问了。因此,客户端要负责原型模式实例的生命周期管理。
在Spring配置文件中将Bean定义成prototype,配置文件修改如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
<!--配置一个bean,将指定类配置给Spring,让Spring创建其对象的实例-->
<bean id="helloSpring" class="com.ssm.HelloSpring" scope="prototype">
<!--为属性赋值-->
<property name="userName" value="张三"></property>
</bean>
</beans>
再次运行测试类,控制台输出结果为false,这说明在prototype作用域下,创建了两个不同的HelloSpring类的实例。