默认情况下,常规的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
——————————————————————————————————————————————————————