Spring Bean 延迟初始化

默认情况下,Spring 容器在初始化过程中会创建和配置所有单例的 Bean。这种提前实例化因为配置环境错误会被立即发现。可以将单例的 Bean 标记为延迟初始化(假如某个 Bean 可能需要加载很大资源,在整个应用程序生命周期中很少用到,可以设置为延迟初始化)。延迟初始化的Bean通常会在第一次使用时被初始化;或者在被非延迟初始化Bean作为依赖对象注入时在会随着初始化该Bean时被初始化

配置方式很简单只需在 标签上指定“lazy-init”属性值为“true”:

<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"); 

Tags:

Add a Comment

电子邮件地址不会被公开。 必填项已用*标注

18 + 4 =