7.9.1: 依赖关系注入之后的行为

Spring可以管理 singleton作用域 Bean的生命周期,Spring可以精确地知道该Bean何时被创建、何时被初始化完成、容器何时准备销毁该Bean实例。

对于 prototype作用域 的Bean,Spring容器仅仅负责创建,当容器创建了Bean实例之后,Bean实例完全交给客户端代码管理,容器不再跟踪其生命周期。

每次客户端请求prototype作用域的Bean时,Spring都会产生一个新的实例,Spring容器无从知道它曾经创建了多少个prototype作用域Bean,也无从知道这些prototype作用域Bean什么时候会被销毁。

对于singleton作用域的Bean,每次客户端代码请求时都返回同一个共享实例,客户端代码不能控制Bean的销毁,Spring容器可以跟踪Bean实例的产生、销毁。容器可以在创建Bean之后,进行某些通用资源的申请;还可以在销毁Bean实例之前,先回收某些资源,比如数据库连接。

对于singleton作用域的Bean,Spring容器知道Bean何时实例化结束、何时销毁,Spring可以管理实例化结束之后和销毁之前的行为。管理Bean的生命周期行为主要有如下两个时机:

① 注入依赖关系之后。

② 即将销毁Bean之前。

依赖关系注入之后的行为:

Spring提供两种方式在Bean全部属性设置成功后执行特定行为:

⑴ 使用 init-method 属性

使用init-method属性指定某个方法应在Bean全部依赖关系设置结束后自动执行,使用这种方法不需将代码与Spring的接口耦合在一起,代码污染小。

⑵ 实现 InitializingBean 接口

该接口提供一个方法void afterPropertiesSet( )throws Exception。Spring容器会在为该Bean注入依赖关系之后,接下来会调用该Bean所实现的afetrPropertiesSet( )方法

Axe.java :

public interface Axe {
	public String chop();
}
Person.java :
public interface Person {
	public void useAxe();
}
SteelAxe.java :
public class SteelAxe implements Axe {

	@Override
	public String chop() {
		return "钢斧砍柴真快";
	}

	public SteelAxe() {
		System.out.println("Spring实例化依赖bean:SteelAxe实例...");
	}
	
	
}
Chinese.java :
public class Chinese implements Person,InitializingBean {
	
	private Axe axe;
	
	public Chinese() {
		System.out.println("Spring实例化主调Bean:Chinese实例...");
	}

	public void setAxe(Axe axe) {
		System.out.println("Spring执行依赖关系注入...");
		this.axe = axe;
	}

	@Override
	public void useAxe() {
		System.out.println(axe.chop());
	}

	public void init(){
		System.out.println("正在执行初始化方法init...");
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("正在执行初始化方法afterPropertiesSet...");
	}

}
bean.xml 核心配置:
<bean id="chinese" class="com.bean.Chinese" init-method="init">
    <property name="axe" ref="steelAxe"></property>
</bean>
  
<bean id="steelAxe" class="com.bean.SteelAxe"/>
Test.java :
public class Test {

	public static void main(String[] args) {
		
		ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
		Person p=(Person) ctx.getBean("chinese");
		p.useAxe();
	}

}
运行Test.java,控制台输出

从运行结果可以看出:依赖注入完成之后,程序先调用afterPropertiesSet方法,在调用init-method属性所指定的方法进行初始化。

如果某个Bean类实现了InitializingBean接口,当该Bean的所有依赖关系被设置完成后,Spring容器自动调用该Bean实例的afterPropertiesSet方法。其结果与采用init-method属性指定生命周期方法几乎一样。但是实现接口污染了代码,是侵入式设计,因此不推荐使用。

相关文章

适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法...
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题...
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结...
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容...