接口或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将无法将其注入到类似

@Autowired

private Foo foo;

但会成功将代理注入到类似

@Autowired

private 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可以将代理注入到字段(或构造函数/方法参数)中,例如

@Autowired

private Foo injectMe;


这么说,如果您正在对interfaces进行编程,那么ScopedProxyMode.INTERFACES就足够了。如果不是,请使用ScopedProxyMode.TARGET_CLASS


至于使用@SessionAttributes,它不是会话范围的Bean的替代方案。会话属性只是对象,它们不是bean。它们不具备bean可能具有的完整生命周期,注入功能和代理行为。

以上是 接口或TARGET_CLASS:我应该选择哪个proxyMode? 的全部内容, 来源链接: utcz.com/qa/434644.html

回到顶部