我只知道用于AOP的动态代理 但是,它似乎也可以用于延迟加载 文章中的以下示例旨在证明这一点 但是我不明白这与普通存取器有什么不同,究竟是什么'懒惰'加载到这里? 任何帮助理解作者想要通过延迟加载意味着什么都是值得赞赏的。
private Category tupleToObject(Serializable[] tuple) {
Category category = new Category((String)tuple[1],
(YearMonthDay) tuple[2]);
category.setId((Long) tuple[0]);
category.setParent(lazyGet((Long) tuple[3]));
return category;
}
protected CategoryItf lazyGet(Long id) {
if (id == null) {
return null;
}
return (CategoryItf)Proxy.newProxyInstance(
CategoryItf.class.getClassLoader(),
new Class[] { CategoryItf.class },
new LazyLoadedObject() {
protected Object loadObject() {
return get(id);
}
});
}
public abstract class LazyLoadedObject implements InvocationHandler {
private Object target;
public Object invoke(Object proxy,
Method method, Object[] args)
throws Throwable {
if (target == null) {
target = loadObject();
}
return method.invoke(target, args);
}
protected abstract Object loadObject();
}
这与以下内容有何不同:
private Category tupleToObject(Serializable[] tuple) {
Category category = new Category((String)tuple[1],
(YearMonthDay) tuple[2]);
category.setId((Long) tuple[0]);
category.setParent(get((Long) tuple[3]));
return category;
}
在这两种情况下,只在需要时才创建父级。
答案 0 :(得分:0)
以下代码段使实现“懒惰”:
private Object target;
public Object invoke(Object proxy,
Method method, Object[] args)
throws Throwable {
if (target == null) {
target = loadObject();
}
您可以看到,无论您多少次调用此代码,每次都会获得相同的对象。所以,实际上它是单身人士。但是它不是在程序开始时创建的,而是仅在第一次需要时才创建。这就是“懒惰”的含义。
答案 1 :(得分:0)
让我试着解释一下我对代码的理解:
在此代码中:
private Category tupleToObject(Serializable[] tuple) {
Category category = new Category((String)tuple[1],
(YearMonthDay) tuple[2]);
category.setId((Long) tuple[0]);
category.setParent(get((Long) tuple[3]));
return category;
}
get()
方法将直接返回实际对象,因此调用tupleToObject()
将使用实际对象填充类别parent。
在此代码中:
private Category tupleToObject(Serializable[] tuple) {
Category category = new Category((String)tuple[1],
(YearMonthDay) tuple[2]);
category.setId((Long) tuple[0]);
category.setParent(lazyGet((Long) tuple[3]));
return category;
}
lazyGet()
方法实际上返回一个代理(不是实际的对象)。对代理的第一个方法调用实际上会触发对象的加载。此处的代理用于延迟实际对象的实际检索,直到实际需要,即延迟加载。
希望这能回答你的问题。