对于prototype作用域的Bean,Spring容器仅仅负责创建,当客户创建了Bean实例之后,Bean实例完全交给客户端代码管理,容器不再跟踪其生命周期。对于singleton作用域的Bean,Spring容器知道Bean何时实例化结束、何时销毁,Spring可以管理实例化结束之后和销毁之前的行为。管理Bean的生命周期行为主要有如下两个时机。
1) 注入依赖关系之后
2) 即将销毁Bean之前
1.注入依赖关系之后
Spring提供两种行为方式在Bean全部属性设置成功后执行特定行为。第一种方式,使用ini-method属性指定某个方法应在Bean全部依赖关系设置结束后自动执行。第二种方式,就是让Bean类实现InitialzingBean接口,该接口提供一个方法,void affterPropertiesSet() throws Exception.下面的例子中包含运用这两种方法。不过要实际开发中建议使用第一种方法,因为代码污染小。
1) 定义个Bean的类。
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接口必须实现的方法
public void afterPropertiesSet() throws Exception
{
System.out.println("正在执行初始化方法 afterPropertiesSet...");
}
}
上面的init()方法名可以不叫这个名字,这个方法主要是用于bean.xml中配置在init-method=””中的方法,而实例了InitializingBean的接口后,就要去重写afterPropertiesSet()的方法。当然,这个Bean中继承了BeanNameAware、ApplicationContextAware接口。
2) 在配置bean.xml文件。
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="steelAxe" class="com.owen.app.service.impl.SteelAxe"/>
<!-- 配置chinese Bean,使用init-method="init"
指定该Bean所有属性设置完成后,自动执行init方法 -->
<bean id="chinese" class="com.owen.app.service.impl.Chinese"
init-method="init">
<property name="axe" ref="steelAxe"/>
</bean>
</beans>
3) 运行结果。
Spring实例化依赖bean:SteelAxe实例…
Sprting实例化主调bean:Chinese实例
Spring调用setAxe()执行依赖注入…
===调用setBeanName===
===setApplicationContext===
正在执行初始化方法afterPropertiesSet…
正在执行初始化方法ini…
钢斧砍柴真棒
4) 说明
如果既采用init-method属性指定初始化方法,又实现InitializingBean接口来指定初始化方法,Spring容器会执行两个初始化方法:先执行InitializingBean接口中定义的方法,然后执行init-method属性指定的方法。
2.即将销毁Bean之前
与制定初始化行为相似,Spring也提供两种方式制定Bean实例销毁之前的特定行为。第一种方式,使用destroy-method属性指定某个方法在Bean销毁之前被自动执行。第二种方法,就是让Chinese类实现DisposableBean接口,这个接口提供了一个方法 :void destroy() throwes Exception.下面用例子来说明。
1) 创建一个Bean.
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());
}
public void close()
{
System.out.println("正在执行销毁之前的方法 close...");
}
public void destroy() throws Exception
{
System.out.println("正在执行销毁之前的方法 destroy...");
}
}
这个类使用了DisposableBean的接口,所以必须去实现destory()的方法,而对于close()的方法,可能不叫这个名字,这个方法名主要是用在bean.xml文件中配置在destory-method=””中的。
2) 配置bean.xml.
<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="steelAxe" class="com.owen.app.service.impl.SteelAxe"/>
<!-- 配置chinese Bean,使用destroy-method="close"
指定该Bean实例被销毁之前,Spring会自动执行指定该Bean的close方法 -->
<bean id="chinese" class="com.owen.app.service.impl.Chinese"
destroy-method="close">
<property name="axe" ref="steelAxe"/>
</bean>
</beans>
3) 写个测试类,用registerShutdownHook()方法来关闭容器中注册的Bean.
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();
}
}
4) 运行结果。
正在执行销毁之前的方法destory…
正在执行销毁之前的方法 close…
5) 说明。
6) 如果既采用destroy-method属性指定初始化方法,又实现DisposableBean接口来指定初始化方法,Spring容器会执行两个初始化方法:先执行DisposableBean接口中定义的方法,然后执行destroy-method属性指定的方法。