一,bean作用域的作用
限制bean对象使用的有效范围 可以通过给bean标签的scope属性赋值来限制bean作用域
二,bean作用域取值
1.singleton
IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。
2.prototype
IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
3.request
每次HTTP请求都会创建一个新的Bean
4.session
同一个Session共享一个Bean实例,不同Session使用不同的实例。
5.global-session
所有的Session共享一个Bean实例。
三,项目搭建
项目目录结构:
BeanScope
package com.beanscope.bean;
public class BeanScope {
public void show() {
System.out.println("BeanScope hashCode:"+this.hashCode());
}
}
UnitTestBase
package com.injection.test;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlpath;// 就是配置spring的bean容器的路径字符串,通过构造器获得
public UnitTestBase() {
}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
/**
* classpath*是当前jar包目录下的所有的jar包下进行的操作, 比如扫描等,classpath只是当前单独一个jar包里的操作。比如在扫描器中,
* classpath只扫描当前包里的class,classpath*则扫描的是当前包目录下所有的包里的class.
*/
springXmlpath = "classpath*:spring-*.xml";
}
try {
/**
* str.split(String regex)作用:根据正则表达式regex,将字符串str, 分割成字符串数组。"[,\\s]+"
* 是一个正则表达式,\\s表示各种空白符,+表示匹配多个。
* StringUtils是org.apache.commons.lang下的一个用于操作Java.lang.String的工具类,
* 使用可能需要手工导入commons-lang-xx.jar 把SpringXmlpath路径拆分开来,
* 因为springXmlpath路径可能是多个路径的拼接,拆分过之后每个路径下的xml都会被扫描识别
*/
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();// 通过扫描xml文件获取并启动容器
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
/**
* T 这是泛型,在你不确定使用什么类型参数的时候,泛型可以代表任意一种类型参数,比较灵活方便
*/
return (T) context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
protected <T extends Object> T getBean(Class<T> clazz) {
try {
return context.getBean(clazz);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
BeanScopeTest
package com.injection.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.beanscope.bean.BeanScope;
@RunWith(BlockJUnit4ClassRunner.class)
public class BeanScopeTest extends UnitTestBase {
public BeanScopeTest() {
super("classpath:spring-bean.xml");
}
/**
* Singleton测试
*/
@Test
public void testSingleton() {
BeanScope beanScope1 = super.getBean("beanScope");
beanScope1.show();
BeanScope beanScope2 = super.getBean("beanScope");
beanScope2.show();
}
/**
* Prototype测试
*/
@Test
public void testPrototype() {
BeanScope beanScope1 = super.getBean("beanScope");
beanScope1.show();
BeanScope beanScope2 = super.getBean("beanScope");
beanScope2.show();
}
}
spring-bean.xml
<?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="beanScope" class="com.beanscope.bean.BeanScope" scope="singleton"></bean>
</beans>
四,代码演示
singleton作用域演示:
1.将spring-bean.xml中的scope设置为 singleton
2.在BeanScopeTest右击运行testSingleton()方法
3.运行结果:发现这两个beanScope是同一个对象,说明了在一个IOC容器中,对于相同beanid的bean仅仅维护一个对象
4.将BeanScopeTest中的代码改为如下:
package com.injection.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.beanscope.bean.BeanScope;
@RunWith(BlockJUnit4ClassRunner.class)
public class BeanScopeTest extends UnitTestBase {
public BeanScopeTest() {
super("classpath:spring-bean.xml");
}
/**
* Singleton测试
*/
@Test
public void testSingleton1() {
BeanScope beanScope1 = super.getBean("beanScope");
beanScope1.show();
}
/**
* Singleton测试
*/
@Test
public void testSingleton2() {
BeanScope beanScope2 = super.getBean("beanScope");
beanScope2.show();
}
}
直接在该类空白处右击运行 得出结果:发现加载了两次xml文件,而且两个beanScope是不同一个对象,说明了在不同的IOC容器中,对于相同beanid的bean返回不同的对象。
protptype作用域演示:
1.将spring-bean.xml中的scope设置为 protptype
2.在BeanScopeTest右击运行testProtptype()方法
3.运行结果:发现这两个beanScope不是同一个对象,说明了在一个IOC容器中,每次获取该类型独享时返回的是不同的对象。