今天学习的内容主要是,depends-on属性的使用,延迟加载lazy-init
通过前面的学习我们知道当我们在引用一个对象时使用ref属性,有时候一个bean的实例需要依赖另外的bean先实例,这种情况又该怎么配置呢,这就是我们今天要学习的第一个属性depends-on
下面我们还是通过一个小程序来描述一下它的主要功能
定义ManagerBean.java,为了演示效果这里将其默认的构造函数显示给出
public class ManagerBean {
private String name;
// 为了演示效果将默认构造显式给出
public ManagerBean(){
System.out.println("ManagerBean constructor");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
定义ExampleBean.java
public class ExampleBean {
private ManagerBean manager;
private String name;
public ExampleBean(){
System.out.println("Example constructor");
}
public ManagerBean getManager() {
return manager;
}
public void setManager(ManagerBean manager) {
this.manager = manager;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置文件bean.xml
<bean id="ExampleBean" class="cn.com.spring.injection.bean.ExampleBean" depends-on="ManagerBean">
<property name="manager"><ref bean="ManagerBean"/></property>
<property name="name" value="ExampleBean"/>
</bean>
<bean id="ManagerBean" class="cn.com.spring.injection.bean.ManagerBean">
<property name="name" value="ManagerBean" />
</bean>
测试程序
public class TestUtils extends TestCase {
private ApplicationContext actx = new FileSystemXmlApplicationContext("bean.xml");
@Test
public void test1(){
ExampleBean exbean = (ExampleBean)actx.getBean("ExampleBean");
System.out.println(exbean.getName());
System.out.println(exbean.getManager().getName());
}
}
执行结果
ManagerBean constructor
Example constructor
ExampleBean
ManagerBean
通过分析结果可知ManagerBean先于ExampleBean构造,去掉depends-on属性后
再次执行的结果
Example constructor
ManagerBean constructor
ExampleBean
ManagerBean
有时候依赖的bean不只是一个,这时候depends-on的配置形式如:depends-on="manager,accountDao"将多个bean有逗号隔开
接下来我们来学习bean的延迟加载,ApplicationContext默认的情况下在启动时会将所有singleton(bean的默认配置) bean都实例化,也就是说提前实例化是初始化的一部分,这样的好处就是如果有配置问题就会在初始化的时候暴露出来,但是有些情况下我们并不希望在初始化的时候实例那么多的bean,我们希望在使用它的时候即调用getBean的时候才对bean进行实例,这时我们可以对该bean进行延迟加载配置。下面我们还是通过一个小例子来演示这个属性的使用
我们将上面的程序保持不变再添加一个LazyBean.java类
public class LazyBean {
private String name;
public LazyBean(){
System.out.println("LazyBean constructor");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置文件添加
<bean id="LazyBean" class="cn.com.spring.injection.bean.LazyBean" lazy-init="true">
<property name="name" value="LazyBean"/>
</bean>
测试程序
@Test
public void test1(){
ExampleBean exbean = (ExampleBean)actx.getBean("ExampleBean");
System.out.println(exbean.getName());
System.out.println(exbean.getManager().getName());
LazyBean lbean = (LazyBean)actx.getBean("LazyBean");
System.out.println(lbean.getName());
}
运行结果如下
ManagerBean constructor
Example constructor
ExampleBean
ManagerBean
LazyBean constructor
LazyBean
结果与预期的一致
这里大家有没有一些疑问呢,如果将lazy-init属性应用于第一个例子中,那么depends-on和lazy-init这两个属性会不会冲突呢,那个又会起作用呢
这个配置情况有多种,笔者只测试了将lazy-init应用于ManagerBean配置中,发现根本不起作用。我们说这个属性只是对singleton bean起作用,那么如果是scope="prototype"或singleton="false"又怎么样呢,大家可以将bean的配置加上scope="prototype" lazy-init="false"试试