Spring参考手册笔记——Bean的延迟加载

本文介绍Spring框架中懒加载Bean的两种方法,通过配置lazy-init或default-lazy-init属性,实现Bean在实际使用时才进行实例化,避免在ApplicationContext初始化过程中的预加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

默认情况下,常规的Bean会在ApplicationContext初始化过程中预先实例化并加载到上下文当中,如果我们想在Bean使用的时候再实例化它,Spring为我们提供了以下两种方式来实现:

我们先定义两个Bean,一个是延迟bean:

package org.dave.demo.spring.lazyinit;

import java.util.Date;

/**
 * @author 一字一码
 * @date 2018/12/28 19:56
 */
public class LazyBean {

    /**
     * 初始化时间
     */
    private Date initTime;

    public Date getInitTime() {
        return initTime;
    }

    public void setInitTime(Date initTime) {
        this.initTime = initTime;
    }

    public LazyBean(){
        initTime = new Date();
        System.out.println("LazyBean init at : "+initTime);
    }
}

另一个是普通的Bean:

package org.dave.demo.spring.lazyinit;

import java.util.Date;

/**
 * @author  一字一码
 * @date 2018/12/28 19:58
 */
public class OrdinaryBean {
    /**
     * 初始化时间
     */
    private Date initTime;

    public Date getInitTime() {
        return initTime;
    }

    public void setInitTime(Date initTime) {
        this.initTime = initTime;
    }

    public OrdinaryBean(){
        initTime = new Date();
        System.out.println("OrdinaryBean init at "+ initTime);
    }
}

第一种方式,在bean元素上使用lazy-init属性配置,lazy-init="true":

创建applicationContext.xml文件,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		">

    <bean id="lazyBean" class="org.dave.demo.spring.lazyinit.LazyBean" lazy-init="true"/>
    <bean id="ordinaryBean" class="org.dave.demo.spring.lazyinit.OrdinaryBean"/>

</beans>

创建测试用例:

package test.org.dave.demo.spring;

import org.dave.demo.spring.lazyinit.LazyBean;
import org.dave.demo.spring.lazyinit.OrdinaryBean;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;

/**
 * @author 一字一码
 * @date 2018/12/28 17:06
 */
public class LazyInitBeanTest {

    /**
     * 使用lazy-init属性
     */
    @Test
    public void lazyInitTest() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
        //休眠2秒后,再从上下文中获取lazyBean
        int sleepTime = 2000;
        try {
            Thread.sleep(sleepTime);
            LazyBean lazyBean = context.getBean("lazyBean", LazyBean.class);
            OrdinaryBean ordinaryBean = context.getBean("ordinaryBean", OrdinaryBean.class);
            Date lazyBeanInitTime = lazyBean.getInitTime();
            Date ordinaryBeanInitTime = ordinaryBean.getInitTime();
            //判断lazyBean和ordinaryBean初始化的时间应该相差2秒
            Assert.assertTrue(lazyBeanInitTime.getTime() - ordinaryBeanInitTime.getTime() >= sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

第二种方式,在beans元素上使用default-lazy-init属性配置,default-lazy-init="true"

创建defaultLazyInit-lazyBeans.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		" default-lazy-init="true">

    <bean id="lazyBean" class="org.dave.demo.spring.lazyinit.LazyBean"/>

</beans>

创建defaultLazyInit-ordinaryBeans.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		" >

    <bean id="ordinaryBean" class="org.dave.demo.spring.lazyinit.OrdinaryBean"/>

</beans>

创建测试用例:

package test.org.dave.demo.spring;

import org.dave.demo.spring.lazyinit.LazyBean;
import org.dave.demo.spring.lazyinit.OrdinaryBean;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;

/**
 * @author 一字一码
 * @date 2018/12/28 17:06
 */
public class LazyInitBeanTest {


    /**
     * 使用default-lazy-init属性
     */
    @Test
    public void defaultLazyInitTest() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"defaultLazyInit-lazyBeans.xml", "defaultLazyInit-ordinaryBeans.xml"});
        //休眠2秒后,再从上下文中获取lazyBean
        int sleepTime = 2000;
        try {
            Thread.sleep(sleepTime);
            LazyBean lazyBean = context.getBean("lazyBean", LazyBean.class);
            OrdinaryBean ordinaryBean = context.getBean("ordinaryBean", OrdinaryBean.class);
            Date lazyBeanInitTime = lazyBean.getInitTime();
            Date ordinaryBeanInitTime = ordinaryBean.getInitTime();
            //判断lazyBean和ordinaryBean初始化的时间应该相差2秒
            Assert.assertTrue(lazyBeanInitTime.getTime() - ordinaryBeanInitTime.getTime() >= sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

以上两种方式的输出结果:

OrdinaryBean init at Fri Dec 28 18:42:49 CST 2018
LazyBean init at : Fri Dec 28 18:42:51 CST 2018

我们可以从输出结果或者测试用例执行结果看出,配置成延迟实例化的bean是生效的。

 

如果您对文章感兴趣,欢迎加群一起交流,QQ群号:862519058
——————————————————————————————————————————————————————

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值