我正在寻找一种存储对象的方法,看来最好的方法是使用代理。我在互联网上找到2个注释,我应该使用其中一个:
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
要么
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS )
而且,与使用相比,代理是最佳的@Component @Scope("session")使用方式@SessionAttributes吗?
@Component @Scope("session")
@SessionAttributes
您需要了解这些注释各自为自己选择的功能。在此处查看javadoc 。继续进行更详细的说明。
首先
创造
一个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将无法将其注入到类似
Foo
@Autowired private Foo foo;
但会成功将代理注入到类似
@Autowired private Printable printable;
所有对代理的调用都将由处理InvocationHandler(通常会执行一些用例特定的逻辑,然后委托给目标对象)。
InvocationHandler
第二注
基于类的代理(使用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。
ScopedProxyMode.INTERFACES
ScopedProxyMode.TARGET_CLASS
至于使用@SessionAttributes,它不是会话范围的Bean的替代方案。会话属性只是对象,它们不是bean。它们不具备bean可能具有的完整生命周期,注入功能和代理行为。