Spring-8.容器中bean的生命周期

Spring可以管理singleton作用域的bean生命周期。(无法管理protype类型的)

对于singleton的bean,管理bean的生命周期有以下两个时机:

(1)注入依赖关系后

(2)即将销毁bean之前

一、依赖关系注入之后的行为

有两种方式:

(1)使用init-method属性

(2)实现initializingBean接口

说明:方式(1)写普通方法init() (方法名任意),在xml中配置。代码污染小。

          方式(2)实现initializingBean接口,并实现方法 void  afterPropertiesSet() throws Exception。

实验1:init-method属性

public class SteelAxe implements Axe
{
	public SteelAxe()
	{
		System.out.println("Spring实例化依赖bean:SteelAxe实例...");
	}
	public String chop()
	{
		return "钢斧砍柴真快";
	}
}
public class Chinese implements Person ,  BeanNameAware, ApplicationContextAware
{
	private Axe axe;
	public void setBeanName(String beanName)
	{
		System.out.println("===setBeanName===");
	}
	public void setApplicationContext(ApplicationContext ctx)
	{
		System.out.println("===setApplicationContext===");
	}
	public Chinese()
	{
		System.out.println("Spring实例化主调bean:Chinese实例...");
	}
	// axe的setter方法
	public void setAxe(Axe axe)
	{
		System.out.println("Spring调用setAxe()执行依赖注入...");
		this.axe = axe;
	}
	public void useAxe()
	{
		System.out.println(axe.chop());
	}
	// 测试用的初始化方法
	public void init()
	{
		System.out.println("正在执行初始化方法 init...");
	}	
}
xml:

<bean id="steelAxe" class="codeEETest.org.crazyit.app.service.impl.SteelAxe"/>
	<!--  配置chinese Bean,使用init-method="init"指定该Bean所有属性设置完成后,自动执行init方法 -->
	
	<bean id="chinese" class="codeEETest.org.crazyit.app.service.impl.Chinese"
		init-method="init">
		<property name="axe" ref="steelAxe"/>
	</bean>
Spring实例化依赖bean:SteelAxe实例...       //xml中从上到下的bean,调用对应的构造方法
Spring实例化主调bean:Chinese实例...        //同上
Spring调用setAxe()执行依赖注入...           //setter方法
===setBeanName===                     
===setApplicationContext===                 //这是两个通知
正在执行初始化方法 init...                  //这里才开始执行xml中配置的初始化
钢斧砍柴真快                                //测试类中执行了p.useAxe();

实验2:initializingBean接口

public class Chinese implements Person,InitializingBean,  BeanNameAware, ApplicationContextAware
{
	private Axe axe;
	public void setBeanName(String beanName)
	{
		System.out.println("===setBeanName===");
	}
	public void setApplicationContext(ApplicationContext ctx)
	{
		System.out.println("===setApplicationContext===");
	}
	public Chinese()
	{
		System.out.println("Spring实例化主调bean:Chinese实例...");
	}
	// axe的setter方法
	public void setAxe(Axe axe)
	{
		System.out.println("Spring调用setAxe()执行依赖注入...");
		this.axe = axe;
	}
	public void useAxe()
	{
		System.out.println(axe.chop());
	}
	// 测试用的初始化方法
	public void init()
	{
		System.out.println("正在执行初始化方法 init...");
	}


	// 实现InitializingBean接口必须实现的方法
	@Override
	public void afterPropertiesSet() throws Exception
	{
		System.out.println("正在执行初始化方法 afterPropertiesSet...");
	}
}
Spring实例化依赖bean:SteelAxe实例...
Spring实例化主调bean:Chinese实例...
Spring调用setAxe()执行依赖注入...
===setBeanName===
===setApplicationContext===
正在执行初始化方法 afterPropertiesSet...     //在init-method属性前执行
正在执行初始化方法 init...
钢斧砍柴真快


小结:

不推荐使用initializingBean接口的方式,污染代码。如果二者同时出现,先执行initializingBena接口。

二、Bean销毁之前

两种方式:

(1)destroy-method属性

(2)DisposableBean接口

说明:方式(1):代码污染小

          方式(2):实现destroy()方法

package org.crazyit.app.service;

public interface Person
{
	public void useAxe();
}
package org.crazyit.app.service;
public interface Axe
{
	public String chop();
}
package org.crazyit.app.service.impl;

import org.springframework.beans.factory.DisposableBean;

import org.crazyit.app.service.*;

public class Chinese implements Person,DisposableBean
{
	private Axe axe;
	public Chinese()
	{
		System.out.println("Spring实例化主调bean:Chinese实例...");
	}
	public void setAxe(Axe axe)
	{
		System.out.println("Spring执行依赖关系注入...");
		this.axe = axe;
	}
	public void useAxe()
	{
		System.out.println(axe.chop());
	}

	//方式1:普通的close()方法,方法名是任意的
	public void close()
	{
		System.out.println("正在执行销毁之前的方法 close...");
	}
	//方式2:接口
	public void destroy() throws Exception
	{
		System.out.println("正在执行销毁之前的方法 destroy...");
	}
}
package org.crazyit.app.service.impl;

import org.crazyit.app.service.*;

public class SteelAxe implements Axe
{
	public SteelAxe()
	{
		System.out.println("Spring实例化依赖bean:SteelAxe实例...");
	}
	public String chop()
	{
		return "钢斧砍柴真快";
	}
}
public class BeanTest
{
	public static void main(String[] args)
	{
		// 以CLASSPATH路径下的配置文件创建ApplicationContext
		AbstractApplicationContext ctx = new
			ClassPathXmlApplicationContext("beans.xml");
		// 获取容器中的Bean实例
		Person p = ctx.getBean("chinese" , Person.class);
		p.useAxe();
		
		// 为Spring容器注册关闭钩子
		ctx.registerShutdownHook();
	}
}
<bean id="steelAxe" class="org.crazyit.app.service.impl.SteelAxe"/>
	<!--  配置chinese Bean,使用destroy-method="close"
		指定该Bean实例被销毁之前,Spring会自动执行指定该Bean的close方法 -->
	<bean id="chinese" class="org.crazyit.app.service.impl.Chinese"
		destroy-method="close">
		<property name="axe" ref="steelAxe"/>
	</bean>
说明:ctx.registerShutdownHook()是为了在JVM里注册关闭钩子(shutdown hook),保证spring容器恰当关闭,执行singleton的析构方法。没有这个将无法看到销毁的执行。

Spring实例化依赖bean:SteelAxe实例...
Spring实例化主调bean:Chinese实例...
Spring执行依赖关系注入...
钢斧砍柴真快

正在执行销毁之前的方法 destroy...
正在执行销毁之前的方法 close...















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值