2017-08-01
Spring Bean 延迟初始化
默认情况下,Spring 容器在初始化过程中会创建和配置所有单例的 Bean。这种提前实例化因为配置环境错误会被立即发现。可以将单例的 Bean 标记为延迟初始化(假如某个 Bean 可能需要加载很大资源,在整个应用程序生命周期中很少用到,可以设置为延迟初始化)。延迟初始化的Bean通常会在第一次使用时被初始化;或者在被非延迟初始化Bean作为依赖对象注入时在会随着初始化该Bean时被初始化
配置方式很简单只需在
<bean id="hello" class="xxxx.HelloImpl" lazy-init="true"></bean>
<bean id="decorator" class="xxxx.HelloDecorator" depends-on="hello">
<constructor-arg index="0" ref="hello"></constructor-arg>
</bean>
“depends-on” 属性指定 Bean 初始化及销毁时的顺序,使用“depends-on”属性指定的 Bean 要先初始化完毕后才初始化当前 Bean。只有 Singleton Bean 能被 Spring 管理销毁,所以当指定的 Bean 都是 Singleton 时,使用“depends-on”属性指定的 Bean 要在指定的 Bean 之后销毁。
若指定多个 Bean 可以用 “;”、“,”、“ ” 分割。
“depends-on”有什么好处?
给出明确的初始化及销毁顺序,否则使用时会看不到准备的资源,销毁时能够正常释放资源。
实例:访问文件系统
ResourceBean 从配置文件中配置文件位置,然后定义初始化方法 init() 中打开指定的文件,然后获取文件流,销毁方法 destroy() 用于在应用程序关闭时调用该方法关闭掉文件流。
public class ResourceBean {
private FileOutputStream fos;
private File file;
public void init() {
System.out.println("ResourceBean:========初始化");
System.out.println("ResourceBean:========加载资源");
try {
this.fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void destory() {
System.out.println("ResourceBean:========销毁");
System.out.println("ResourceBean:========释放资源");
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setFile(File file) {
this.file = file;
}
public FileOutputStream getFos() {
return fos;
}
}
DependentBean 中会注入 ResourceBean,并从 ResourceBean 中获取文件流写入内容。
public class DependentBean {
ResourceBean resourceBean;
public void init() throws IOException {
System.out.println("DependentBean:=======初始化");
resourceBean.getFos().write("DependentBean:=======初始化=====".getBytes());
}
public void destroy() throws IOException {
System.out.println("DependentBean:=======销毁");
resourceBean.getFos().write("DependentBean:=======销毁=====".getBytes());
}
public void setResourceBean(ResourceBean resourceBean) {
this.resourceBean = resourceBean;
}
public void write(String ss) throws IOException {
System.out.println("DependentBean:=======写资源");
resourceBean.getFos().write(ss.getBytes());
}
}
配置文件如下:
<bean id="resourceBean" class="xxxx.ResourceBean"
init-method="init"
destroy-method="destory">å
<property name="file" value="test.txt"></property>
</bean>
<bean id="dependentBean" class="xxxx.DependentBean"
init-method="init"
destroy-method="destory"
depends-on="resourceBean">
<property name="resourceBean" ref="resourceBean"></property>
</bean>
需要注意,代码中一点要注册销毁回调,否则定义的销毁方法不执行 :
context.registerShutdownHook();
DependentBean dependentBean = context.getBean("dependentBean", DependentBean.class);
dependentBean.write("aaa");