我现在正在阅读一本韩语编写的Spring书籍,但是我的英语很差。请您理解。
在这本书中,它说如果使用接口,Spring的AOP将使用动态代理来初始化类,如果不使用接口,则使用CGLIB来初始化类。我不太明白这是什么意思。你能帮我理解其深层含义吗?
我不知道这个问题是否愚蠢。但我只是好奇。谢谢。
InvocationHandler
仅有一个需要实现的方法:public Object invoke(Object proxy, Method method, Object[] args)
与此同时,调用该方法的客户端无法区分代理和其底层对象表示之间的区别,也不应该关心。
为类创建动态代理,而不是接口,不太简单。虽然 Java 的 Proxy
只是一个实现接口或一组接口的运行时实现,但对象并不一定要实现接口。因此,代理类需要字节码生成,这就是像 cglib 这样的库发挥作用的地方。cglib 提供了对代理类的支持,因为它可以动态生成字节码(即类文件),这意味着它可以在运行时以 Java 的 Proxy
可以在运行时实现接口的方式扩展类。
代理有许多用途。其中一个用途是延迟加载。延迟加载允许对象图中的对象只在需要时加载。我们可以在需要访问它们时按需加载它们,而不是立即将它们全部加载到内存中,这可能会很昂贵且消耗资源。这可以通过使用代理来实现。代理表示惰性加载的对象。该对象本身可能是从数据库加载的,在其代理上调用方法之前不会加载该对象。拦截方法调用的代理将加载对象到内存中并将方法调用委托给它。
这是延迟加载实现的示例:
public abstract class LazilyLoadedObject implements InvocationHandler {
private Object target;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (target == null) {
target = loadObject();
}
return method.invoke(target, args);
}
/**
* Loads the proxied object. This might be an expensive operation
* or loading lots of objects could consume a lot of memory, so
* we only load the object when it's needed.
*/
protected abstract Object loadObject();
}
以上的InvocationHandler
将被传递给代理对象,以便代理对象上调用的方法将由InvocationHandler
处理。该处理程序会检查对象是否已加载。如果没有加载,它将调用loadObject()
,这可能是一些检索对象的数据库查询。
InvocationHandler
正在调用target
上的方法,这是实际对象,而不是代理。如果我改为调用return method.invoke(proxy, args)
,那么就会出现无限循环。 - Tyler Treat