Spring Bean的作用域和生命周期

Spring Bean的作用域

我们知道Spring中的对象是通过Bean的的方式来进行管理的,Bean的作用域默认是单利的(singleton)
xml 中的配置如下:

<bean id="bean" class="cn.zhuoqianmingyue.ioc.scope.Bean" scope="singleton"></bean>

进行测试:
我们获取3次Bean类的实例对象,通过打印对象的哈希值来进行判断。
测试代码如下:

public class ScopeTest {
	@Test
	public void singleton() {
		ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-scope.xml");
		Bean user = (Bean)appliction.getBean("bean");
		Bean user2 = (Bean)appliction.getBean("bean");
		Bean user3 = (Bean)appliction.getBean("bean");
		System.out.println(user.toString());
		System.out.println(user2.toString());
		System.out.println(user3.toString());
	}
}

测试结果:
在这里插入图片描述

通过上面代码测试我们证实了Spring 配置 scope=“singleton” 创建实例对象默认是单例的。
在每个Spring IoC容器中,一个bean定义对应只会有唯一的一个bean实例。

在实际开发中可能我们需要实例对象不想设置成单利的 ,Spring的作用域 还为我们提供了 另外六种分别为:

1. prototype
一个bean定义可以有多个bean实例。原型模式 每次创建的都是新的实例对象。
2. request
一个bean定义对应于单个HTTP 请求的生命周期。也就是说,每个HTTP 请求都有一个bean实例,且该实例仅在这个HTTP 请求的生命周期里有效。该作用域仅适用于WebApplicationContext环境。相当于调用 request.setAttribute(“bean”,Bean);
3. session
一个bean 定义对应于单个HTTP Session 的生命周期,也就是说,每个HTTP Session 都有一个bean实例,且该实例仅在这个HTTP Session 的生命周期里有效。该作用域仅适用于WebApplicationContext环境。相当于 调用 request.getSession().setAttribute(“bean”,Bean);
4. application
一个bean 定义对应于单个ServletContext 的生命周期。该作用域仅适用于WebApplicationContext环境。相当于调用
servletContext.setAttribute(“bean”,Bean);
5. websocket
一个bean 定义对应于单个websocket 的生命周期。该作用域仅适用于WebApplicationContext环境。这个没有自己没有实际应用过。不太了解
6. globalSession
一个bean 定义范围限定为全局HTTP的生命周期Session,只适用于基于portlet的web应用程序的上下文。这个没有自己没有实际应用过。不太了解

Spring Bean的生命周期

我们拿人来举例,生命周期就是 一个婴儿从诞生到变老死亡的的过程。在Spring中由于Bean的实例化都是Spring框架来完成的,这个过程我们是无法进行干预的。但是Spring为我们提供了2个回调方法 init-method 和destory-method。
接下来我们进行回调方法配置来观察Spring的声明周期执行过程:
首先创建名称为Bean类,创建init 和destroy方法代码如下:

package cn.zhuoqianmingyue.ioc.scope;

public class Bean {
	
	public void init() {
		System.out.println("init......");
	}
	public void destroy() {
		System.out.println("destroy......");
	}
	
}

将Bean类配置到Spring配置文件中,并通过init-method 和destroy-method指定初始化和销毁调用的方法。

<bean id="bean" class="cn.zhuoqianmingyue.ioc.scope.Bean" init-method="init" destroy-method="destroy"></bean>

进行测试:
首先我们测试初始化的操作,通过实例化Spring容器看看 init方法是否被调用。
测试代码如下:

public class LifecycleTest {
	@Test
	public void beanLifecycleInit() {
		ApplicationContext application = new ClassPathXmlApplicationContext("ioc-lifecycle.xml");
	}
}

测试结果:
在这里插入图片描述
由于ApplicationContext 没有提供容器关闭的操作,我们通过ClassPathXmlApplicationContext 来完成我们的容器关闭操作
测试代码如下:

	@Test
	public void beanLifecycleInitAndDestroy() {
		ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("ioc-lifecycle.xml");
		Bean bean = (Bean)application.getBean("bean");
		application.close();
	}

测试结果:
在这里插入图片描述
Spring的Bean是在我们的容器初始化时进行创建,当我们的容器关闭或者销毁时Bean会进行销毁。

需要注意的是Bean的销毁只能操作作用域是单利的Bean,对于非单利的Bean Spring只是负责创建,而销毁的操作和我们普通new 出来的实例对象一样通过JVM垃圾回收进行进行销毁的。

查看源码
下载源码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值