Java 动态加载与延迟加载
我只知道动态代理用于AOP。Java 动态加载与延迟加载,java,lazy-loading,Java,Lazy Loading,我只知道动态代理用于AOP。 但是,它似乎也可以用于延迟加载。 以下文章示例旨在说明这一点。 但是,我无法理解这与普通访问器有何不同,这里“延迟”加载的究竟是什么? 任何有助于理解作者所说的延迟加载的意思的帮助都是非常感谢的 private Category tupleToObject(Serializable[] tuple) { Category category = new Category((String)tuple[1], (YearMonthDay)
但是,它似乎也可以用于延迟加载。
以下文章示例旨在说明这一点。
但是,我无法理解这与普通访问器有何不同,这里“延迟”加载的究竟是什么?
任何有助于理解作者所说的延迟加载的意思的帮助都是非常感谢的
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;
}
在这两种情况下,只有在需要时才创建父级。以下代码片段使实现“懒惰”:
您可以看到,无论调用此代码多少次,每次都会得到相同的对象。所以,实际上是单身。但是,它不是在程序开始时创建的,而是仅在第一次需要时创建的。这就是这里“懒惰”的意思 让我试着从我对代码的理解来解释: 在此代码中:
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;
}
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;
}
get()
方法将直接返回实际对象,因此调用tupleToObject()
将用实际对象填充类别父对象
在本规范中:
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;
}
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()
方法实际上返回一个代理(而不是实际的对象)。代理上的第一个方法调用实际上会触发对象的加载。这里的代理用于延迟实际对象的实际检索,直到实际需要它为止,即延迟加载
希望这能回答您的问题。经过编辑,使我的问题更加集中。AlexR,我没有得到我的答案,也无法将我的问题作为新问题提出来,现在问题太少了,请在这里帮助我。。即使是“get”也只会在第一次调用时返回实例?这有什么不同吗?我可以理解动态加载位,但不能理解“lazy”在这里的适用性。
tupleToObject()
-->get()
-->loaded object
。将其与:tupleToObject()
-->lazyGet()
-->PROXY
。如果没有调用代理上任何方法的代码
,实际对象将永远不会加载。如果在代码中的某个地方访问代理,即PROXY.xxx
,则PROXY
-->loaded object
称为lazy,因为它不直接加载。