Spring-Bean的深究(三)

节点Bean属性:scope:

Spring简单的实例(一)中,我们说过Bean的生命周期,知道默认情况下Bean是处于单例状态,这里还需要再提一下:


首先抛出一个问题:在Spring中我们通过getBean(name)获得的实例,那么我们每次获取的实例化对象是否唯一?

       我们可以通过代码来验证结论:

在配置文件Beans.xml中配置(基本不变):

	<bean id="userBean" class="com.xuli.spring.implement.UserBean"></bean>

接着直接可以写测试方法,我们可以通过“==”进行测试:

	 @Test
	/*
	 * 测试Bean在初始化时,是否重新实例了一个新的实例
	 */
	public void UserTest3() {
		ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
		UserBean user = (UserBean) context.getBean("userBean");
		UserBean user1 = (UserBean) context.getBean("userBean");
		System.out.println(user == user1);	
	}

运行结果如下所示:

Spring-Bean的深究(三)_第1张图片

如此可以验证之前的结论:

默认Bean是单例,任何人获取该Bean实例的都为同一个实例。

在配置文件节点Bean下有一个属性scope,在默认情况下它是这样的:scope= “singleton”,是单例! :

<bean id="userBean" class="com.xuli.spring.implement.UserBean" scope="singleton"></bean>

将scope属性指定为prototype:

<bean id="userBean" class="com.xuli.spring.implement.UserBean" scope="prototype"></bean>

这时候我们在运行测试:是不是发现控制台打印出false 了。

Spring-Bean的深究(三)_第2张图片

这时就不是唯一的实例对象了!

bean元素scope属性配置Bean的作用域这里在强调一下:

<bean>元素scope属性,在spring规范中scope属性有五个取值:

1. scope="singleton" 单例,在Spring IoC容器中仅存在一个Bean实例(默认的scope)

默认情况下:托管给spring默认在spring容器中只有一个Bean实例对象.

2. scope="prototype" 多例,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()

3. scope="request" 用于web开发,该作用域仅适用于WebApplicationContext环境.

每次HTTP请求都会创建一个新的Bean,将Bean放入request范围,request.setAttribute("xxx"),在同一个request 获得同一个Bean

4. scope="session" 用于web开发, 该作用域仅适用于WebApplicationContext环境.

同一个HTTP Session 共享一个Bean,不同Session使用不同Bean,将Bean 放入Session范围

5. scope="globalSession"该作用域仅适用于WebApplicationContext环境.

一般用于Porlet应用环境 , 分布式系统存在全局session概念,如果不是porlet环境,globalSession 等同于Session . Porlet是Servlet的一个升级,Porlet主要用于分布式系统.

节点Bean属性Lazy-init,init-method,destroy-method:

在默认的情况下IOC容器在启动时会初始化Bean,但是我们可以通过Lazy-init=“true”来延迟初始化Bean,这时只有第一次获取Bean时才会初始化Bean。配置代码如下:

<bean id="userBean" class="com.xuli.spring.implement.UserBean" Lazy-init="true"></bean>

如果想要对所有Bean都是用延迟初始化那么可以在Beans后加这样的属性:

<beans default-lazy-init="true"...</beans>

这样就OK了。

如果我们想在UserBean实例化时,调用初始化方法可以使用这样的节点属性init-method,销毁方法也可以通过destory-method调用。

具体实现代码如下:

首先在Beans.xml下配置:

<bean id="userBean" class="com.xuli.spring.implement.UserBean" scope="singleton" init-method="init" destroy-method="destroy">

在UserBean中加入初始化和销毁方法,init,destroy 方法。

代码如下:

/*
 * 实现PersonBean的接口
 */
public class UserBean implements UserBeanimpl {

	@Override
	public void show() {
		// TODO Auto-generated method stub
		System.out.println("hello xuli ");
	}
	//初始化方法
	public void init(){
		
		System.out.println("Bean被初始化了");
	}
	//销毁方法
	public  void destroy(){
		System.out.println("Bean被销毁了");
	}

}

测试方法:

	 @Test
	// 使用类构造器直接实例化测试
	public void UserTest() {
		// ApplicationContext context = new
		// ClassPathXmlApplicationContext("Beans.xml");
		// 读取配置Bean文件

		ApplicationContext context = new FileSystemXmlApplicationContext("classpath:Beans.xml");
		// 获得在Bean.xml里注入的Bean对象
		UserBean user = (UserBean) context.getBean("userBean");
		// 调用其对象内的方法
		user.show();
	}

是不是发现销毁方法无效?

这里可以在测试方法内调用user.destroy()方法直接销毁。

也可以通过关闭spring容器调用destory方法,这样不需要user.destory()。demo:

	 @Test
	// 使用类构造器直接实例化测试
	public void UserTest() {
		// ApplicationContext context = new
		// ClassPathXmlApplicationContext("Beans.xml");
		// 读取配置Bean文件

		ApplicationContext context = new FileSystemXmlApplicationContext("classpath:Beans.xml");
		// 获得在Bean.xml里注入的Bean对象
		UserBean user = (UserBean) context.getBean("userBean");
		// 调用其对象内的方法
		user.show();
	        ((AbstractApplicationContext) context).close();
	}

这样就可以销毁啦。

测试结果:

Spring-Bean的深究(三)_第3张图片


你可能感兴趣的:(Spring-Bean的深究(三))