bean的生命周期——Spring对bean的管理(三)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34598667/article/details/83269561

本章案例基于上节,看不懂的请先看上节——bean的作用域:
https://blog.csdn.net/qq_34598667/article/details/83269250


bean的生命周期

1、bean的实例化:bean在何时被实例化?
2、bean的初始化:init-method:指定初始化回调方法,在实例化 bean 时,立即调用该方法
3、bean的销毁:destroy-method:销毁回调方法,只有从容器中移除 bean 之后,才能调用该方法。
4、默认的初始化和销毁方法
beans标签内部 default-init-method=“init” default-destroy-method=“destroy”


bean在何时被实例化?

大家已经学过servlet的生命周期了,servlet是被web容器进行管理的,而servlet的实例化有两种方式:web容器在加载时和servlet被访问时。与servlet类似,bean是被spring容器所管理的,所以bean的实例化无外乎两种情况:
1、Spring容器启动时。
2、调用getBean()方法时。
这里我们要注意的是,bean的实例化时间跟Bean的作用域也有一定的关系,我们以上节内容spring bean的作用域为基础举例

1)当bean的作用域为singleton时

修改Demo类,添加构造方法:

public class Demo {
	public Demo(){
		System.out.println("正在实例化...");
	}
	private String name;
}

然后修改spring.xml的配置文件如下,使用scope的默认值:

<?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="demo" class="com.oak.junit.day01.Demo"></bean>
</beans>

即bean的作用域为singleton时,我们修改测试类的代码,添加测试方法为:

	@Test
	public void testLife(){
		//实例化Spring容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
	}

控制台输出:
正在实例化...
说明了当bean的作用域为singleton时,bean对象是在Spring容器启动时就进行创建了。即默认情况下会在容器启动时初始化bean。
我们也可以指定bean的初始化时机为在调用getBean()方法时被初始化,使用bean元素的lazy-init属性:
lazy-init:true,延迟初始化的 bean 告诉 Ioc 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。
修改bean节点代码为:

	<!-- 构造器实例化 -->
	<bean id="demo" class="com.oak.junit.day01.Demo" scope="prototype"
	lazy-init="true"></bean>

直接测试发现并没有任何输出,更改测试方法为:

	@Test
	public void testLife(){
		//实例化Spring容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
		Demo demo=ctx.getBean("demo",Demo.class);
	}

重新测试发现控制台输出:
正在实例化...
则说明了lazy-init=”true”指定了不要在Spring容器启动时对这个bean进行实例化。

如果想对所有bean都应用延迟初始化,可以在根节点beans设置default-lazy-init=“true”,代码如下:

<?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" 
        default-lazy-init="true">

    ......

</beans>


2)当bean的作用域为prototype时

修改spring.xml配置文件,删除bean节点的lazy-init=”true”,代码如下:

	<!-- 构造器实例化 -->
	<bean id="demo" class="com.oak.junit.day01.Demo" scope="prototype"></bean>

增加测试方法如下:

	@Test
	public void testLifePrototype(){
		//实例化Spring容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
	}

进行测试发现没有任何输出,修改测试方法,增加getBean()方法的调用

	@Test
	public void testLifePrototype(){
		//实例化Spring容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
		Demo demo=ctx.getBean("demo",Demo.class);
	}

控制台输出:
正在实例化...
说明当bean的作用域为prototype时,bean对象并不会在Spring容器启动时就进行创建。 bean对象将会在调用getBean()方法时进行创建。


bean的初始化

我们希望在bean被初始化的时候,就初始化某些资源。为了达到这样的目的,我们可以给类添加初始化方法:

public class Demo {
	//定义初始化方法
	public void init(){
		System.out.println("正在被初始化...");
	}
	public Demo(){
		System.out.println("正在实例化...");
	}
	private String name;
}

在Spring.xml中为bean指定初始化方法,使用bean元素的init-method属性:

     <!-- 构造器实例化 -->
	<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false" init-method="init"></bean>

执行测试方法:

	@Test
	public void testInit(){
		//实例化Spring容器
		ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
	}

控制台输出:

正在实例化...
正在初始化...

bean的销毁

现在我们又希望在bean被销毁的时候,就释放或关闭某些资源。为了达到这样的目的,我们可以给类添加指定的销毁方法:

public class Demo {
	//初始化方法
	public void init(){
		System.out.println("正在初始化...");
	}
	public Demo(){
		System.out.println("正在实例化...");
	}
	//销毁方法
    public void destroy() {
        System.out.println("释放初始化的资源");
    }
	private String name;	
}

在Spring.xml中为bean指定初始化方法,使用bean元素的init-method属性:

     <!-- 构造器实例化 -->
	<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false" init-method="init" 	destroy-method="destroy"></bean>

添加测试方法并执行:

	@Test
	public void testDestory(){
		//实例化Spring容器
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
		//正常关闭Spring容器
		ctx.close();
	}

控制台输出:

正在实例化...
正在初始化...
释放初始化的资源

PS:bean销毁的时机

bean到底是什么时候销毁的呢?如果没有人为地删除它,默认该bean一直在Spring容器中, 也就是说随着Spring容器的关闭,该bean才会被销毁。

默认的初始化和销毁方法

在beans标签内部添加 default-init-method=“init” default-destroy-method=“destroy”
修改spring.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"
        default-init-method="init" 
        default-destroy-method="destroy">
	       <!-- 构造器实例化 -->
	<bean id="demo" class="com.oak.junit.day01.Demo" lazy-init="false"></bean>
</beans>

添加测试方法:

	@Test
	public void testLife(){
		//实例化Spring容器
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml"); 
		ctx.close();
	}

控制台输出:

正在实例化...
正在初始化...
释放初始化的资源

下一章:IOC

猜你喜欢

转载自blog.csdn.net/qq_34598667/article/details/83269561