gpt4 book ai didi

spring - 接口(interface)或 TARGET_CLASS : Which proxyMode should I choose?

转载 作者:IT老高 更新时间:2023-10-28 13:45:56 24 4
gpt4 key购买 nike

我正在寻找一种方法来存储我的对象,似乎最好的方法是使用代理。我在互联网上找到了 2 个注释,我应该使用哪个:

@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )

此外,代理是不是比使用 @Component 最好的使用方式
@Scope("session")
还是使用 @SessionAttributes?

最佳答案

您需要了解每个注释的作用,以便为您自己选择。请参阅 javadoc,here .继续进行更详细的说明。

第一个

@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)

创造

a JDK dynamic proxy implementing all interfaces exposed by the class of the target object

换句话说,代理将是目标对象类实现的接口(interface)的子类型,但不会是目标对象类本身的子类。

基本上 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 类型,因此您不能将其注入(inject)该类型的任何目标。例如,Spring 将无法将其注入(inject)到类似的字段中

@Autowired
private Foo foo;

但会成功地将代理注入(inject)到类似的字段中

@Autowired
private Printable printable;

对代理的所有调用都将由 InvocationHandler 处理(通常执行一些特定于用例的逻辑,然后委托(delegate)给目标对象)。


第二个注释

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )

创造

a class-based proxy (uses CGLIB).

除了接口(interface),使用CGLIB Spring 将能够创建一个代理,其类是目标类的子类。本质上,它执行以下操作

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 的构造函数)。所有对代理的调用都将被提供的回调拦截(通常执行一些特定于用例的逻辑,然后委托(delegate)给目标对象)。

由于代理类扩展了 Foo,Spring 可以像

一样将代理注入(inject)到字段(或构造函数/方法参数)中
@Autowired
private Foo injectMe;

如果你是 programming to interfaces,就这么说吧,那么 ScopedProxyMode.INTERFACES 就足够了。如果不是,请使用 ScopedProxyMode.TARGET_CLASS


至于使用@SessionAttributes ,它不是 session 范围 bean 的替代品。 session 属性只是对象,它们不是 bean。它们不具备 bean 可能具有的完整生命周期、注入(inject)功能、代理行为。

关于spring - 接口(interface)或 TARGET_CLASS : Which proxyMode should I choose?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21759684/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com