Spring bean的延迟加载

来源:互联网 发布:mac用ie浏览器 编辑:程序博客网 时间:2024/06/04 17:41

Spring配置文件中的beans默认情况下是及时加载的,当配置初始化加载bean比较多时,一次性实例化会消耗很多时间,此时可以通过bean节点的属性lazy-init来实现延迟加载。一个延迟初始化bean将告诉IOC容器是在启动时还是在第一次被用到时实例化。

下面我们用一个例子演示一下延时加载:

public class Employee {    private String name;    private Address address;    public Employee() {        System.out.println("Employee Constructor");    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}
public class Address {    public Address() {        System.out.println("Address Constructor");    }    private String city;    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }}

Spring配置:

    <bean id="employeeBean" class="com.fh.spring.Employee"/>    <bean id="addressBean" class="com.fh.spring.Address"        lazy-init="true" />

执行类:

public class Main {    public static void main(String[] args) {        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(                new String[] { "ApplicationContextTest.xml" });        System.out.println("After initialization");        Employee ee = (Employee) applicationContext.getBean("employeeBean");        applicationContext.getBean("addressBean");    }}

输出结果:

Employee ConstructorAfter initializationAddress Constructor

通过输出结果可以看出Spring容器初始化的时候默认实例化Employee类的对象,而Address设置了延迟加载只有在调用的时候才会进行实例化。

需要说明的是,如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化singleton bean时,它必须也确保所有上述singleton 依赖bean也被预先初始化,当然也包括设置为延迟实例化的bean。因此,如果IOC容器在启动的时候创建了那些设置为延迟实例化的bean的实例。
修改配置文件如下:

   <bean id="employeeBean" class="com.fh.spring.Employee">      <property name="address" ref="addressBean" />   </bean>   <bean id="addressBean" class="com.fh.spring.Address"        lazy-init="true" />

再测执行Main类输出结果如下:

Employee ConstructorAddress ConstructorAfter initialization

可以看出虽然Address设置成延迟加载,但是由于有其他的类依赖于他,IOC容器也会进行提前实例化。

0 0