接口或TARGET_CLASS:我应该选择哪个proxyMode?
我正在寻找一种存储对象的方法,看来最好的方法是使用代理。我在互联网上找到2个注释,我应该使用其中一个:
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
要么
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )
而且,与使用相比,代理是最佳的@Component @Scope("session")
使用方式@SessionAttributes
吗?
回答:
您需要了解这些注释各自为自己选择的功能。在此处查看javadoc
。继续进行更详细的说明。
首先
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
创造
一个JDK动态代理,实现目标对象类公开的 所有 接口
换句话说,代理将是目标对象的类实现的接口的子类型,但不会是目标对象的类本身的子类。
本质上,Spring执行以下操作
public class Example { public static void main(String[] args) throws Exception {
Foo target = new Foo();
InvocationHandler proxyHandler = ... // some proxy specific logic, likely referencing the `target`
// works fine
Printable proxy = (Printable) Proxy.newProxyInstance(Example.class.getClassLoader(),
target.getClass().getInterfaces(), proxyHandler);
// not possible, ClassCastException
Foo foo = (Foo) proxy;
}
public static class Foo implements Printable {
@Override
public void print() {
}
}
public interface Printable {
void print();
}
}
返回的代理将不是此类型Foo
,因此您不能将其注入该类型的任何目标中。例如,Spring将无法将其注入到类似
@Autowiredprivate Foo foo;
但会成功将代理注入到类似
@Autowiredprivate Printable printable;
所有对代理的调用都将由处理InvocationHandler
(通常会执行一些用例特定的逻辑,然后委托给目标对象)。
第二注
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )
创造
基于类的代理(使用CGLIB)。
除了接口之外,Spring还可以使用CGLIB创建一个代理,该代理的类是目标类的子类。本质上,它执行以下操作
Foo target = new Foo();net.sf.cglib.proxy.Enhancer enhancer = new net.sf.cglib.proxy.Enhancer();
enhancer.setInterfaces(target.getClass().getInterfaces());
enhancer.setSuperclass(target.getClass());
net.sf.cglib.proxy.MethodInterceptor interceptor = ... // some proxy specific logic, likely referencing the `target`
enhancer.setCallback(interceptor);
// works fine
Foo proxy = (Foo) enhancer.create();
CGLIB创建一个新类,Foo
并将其实例化(调用的构造函数Foo
)。提供的回调将拦截对代理的所有调用(该回调通常执行一些用例特定的逻辑,然后委托给目标对象)。
由于代理类已扩展Foo
,Spring可以将代理注入到字段(或构造函数/方法参数)中,例如
@Autowiredprivate Foo injectMe;
这么说,如果您正在对interfaces进行编程,那么ScopedProxyMode.INTERFACES
就足够了。如果不是,请使用ScopedProxyMode.TARGET_CLASS
。
至于使用@SessionAttributes
,它不是会话范围的Bean的替代方案。会话属性只是对象,它们不是bean。它们不具备bean可能具有的完整生命周期,注入功能和代理行为。
以上是 接口或TARGET_CLASS:我应该选择哪个proxyMode? 的全部内容, 来源链接: utcz.com/qa/434644.html