实现对象属性的lazy-loading(延迟加载)

Posted 科比爱徒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现对象属性的lazy-loading(延迟加载)相关的知识,希望对你有一定的参考价值。

 一、延迟加载器LazyLoader作用:
       说到延迟加载,应该经常接触到,尤其是使用Hibernate的时候,本篇将通过一个实例分析延迟加载的实现方式。LazyLoader接口继承了Callback,因此也算是CGLib中的一种Callback类型。

二、示例:
        首先定义一个实体类LoaderBean,该Bean内有一个需要延迟加载的属性对象PropertyBean。

LoaderBean.java:

public class LoaderBean {  
    private String loaderName;  
    private int loaderValue;  
    private PropertyBean propertyBean;  
    public LoaderBean(){  
        this.loaderName="loaderNameA";  
        this.loaderValue=123;  
        this.propertyBean=createPropertyBean();  
    }  
    protected PropertyBean createPropertyBean(){  
        Enhancer enhancer=new Enhancer();  
        enhancer.setSuperclass(PropertyBean.class);  
        return (PropertyBean)enhancer.create(PropertyBean.class,new ConcreteClassLazyLoader());  
    }  
      
    //setter/getter...  
}

PropertyBean.java:
public
class PropertyBean { private String propertyName; private int propertyValue; //setter/getter }

在LoaderBean的构造方法中,对属性Bean进行了代理类生成,使用了CGLib中的LazyLoader回调接口。

 
public class ConcreteClassLazyLoader implements LazyLoader{  
    public Object loadObject() throws Exception {  
        System.out.println("LazyLoader loadObject() ...");  
        PropertyBean bean=new PropertyBean();  
        bean.setPropertyName("lazy-load object propertyName!");  
        bean.setPropertyValue(11);  
        return bean;  
    }  
}  

验证延迟加载

LoaderBean loader=new LoaderBean();  
System.out.println(loader.getLoaderName());  
System.out.println(loader.getLoaderValue());  
PropertyBean propertyBean=loader.getPropertyBean();//访问延迟加载对象  
System.out.println(propertyBean.getPropertyName());  
System.out.println(propertyBean.getPropertyValue());  
System.out.println("after...");  
//当再次访问延迟加载对象时,就不会再执行回调了  
System.out.println(propertyBean.getPropertyName()); 

控制台输出

loaderNameA  
123  
LazyLoader loadObject() ...  
lazy-load object propertyName!  
11  
after...  
lazy-load object propertyName!

       注意,第一次获取property bean的属性时,会触发代理类回调方法。第二次再获取property bean的属性时,就直接返回属性值而不会再次触发代理类回调方法了。

       可见,延迟加载原理:对需要延迟加载的对象添加代理,在获取该对象属性时先通过代理类回调方法进行对象初始化。在不需要加载该对象时,只要不去获取该对象内属性,该对象就不会被初始化了(在CGLib的实现中只要去访问该对象内属性的getter方法,就会自动触发代理类回调)。

以上是关于实现对象属性的lazy-loading(延迟加载)的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis延迟加载和缓存

MyBatis延迟加载和缓存

Hibernate延迟加载

前端优化 lazy-load(懒加载)

Hibernate延迟加载机制原理

如何在休眠/弹簧中更新多对多集合(延迟加载)?