有人可以解释一下 spring @ScopedProxy
注释的用法吗?我认为它与会话范围的 bean 有关,但我不太确定是什么。
在我使用范围时,我使用了没有 @ScopedProxy
注释(或没有 aop 范围代理)的会话范围 bean,所以我非常确定如何正确使用它。
Section 3.4.4.5 的 spring 文档很好地解释了它:
(请注意,下面的“userPreferences”bean 定义是不完整的):
<!-- an HTTP Session-scoped bean -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<!-- a singleton-scoped bean -->
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
从上面的配置中可以明显看出,单例 bean 'userManager' 被注入了对 HTTP 会话范围 bean 'userPreferences' 的引用。这里的重点是'userManager' bean 是一个单例......每个容器将只实例化一次,并且它的依赖项(在这种情况下只有一个,'userPreferences' bean)也只会被注入(一次! )。
这意味着“userManager”将(概念上)只对完全相同的“userPreferences”对象进行操作,即最初注入的对象。
当您将 HTTP 会话范围的 bean 作为依赖项注入协作对象(通常)时,这不是您想要的。相反,我们想要的是每个容器有一个单独的“userManager”对象,然后,在 HTTP 会话的生命周期内,我们希望查看和使用特定于所述 HTTP 会话的“userPreferences”对象。
相反,您需要的是注入某种对象,该对象公开与 UserPreferences 类完全相同的公共接口(理想情况下是一个 UserPreferences 实例的对象),并且足够聪明,能够启动并获取真正的 UserPreferences 对象来自我们选择的任何底层范围机制(HTTP 请求、会话等)。然后我们可以安全地将这个代理对象注入到 'userManager' bean 中,这将很高兴地不知道它所持有的 UserPreferences 引用是一个代理。
在我们的例子中,当一个 UserManager 实例调用依赖注入的 UserPreferences 对象上的一个方法时,它实际上会调用代理上的一个方法......然后代理将关闭并从中获取真正的 UserPreferences 对象(在这种情况下) HTTP Session,并将方法调用委托给检索到的真实 UserPreferences 对象。
这就是为什么在将请求范围、会话范围和全局会话范围的 bean 注入协作对象时需要以下正确且完整的配置:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
在尝试了此处指定的各种不同选项和 spring 文档之后,由于某种原因,我发现 Spring MVC 在您使用 @Controller 注释并且您的 web 应用程序中有多个这样的控制器时会奇怪地自动装配控制器。将注解修改为@RestController (value="UniqueControllerv1"),问题解决。
@ScopedProxy
已替换为@RequestScope
和其他。您可以在此处找到示例:logicbig.com/tutorials/spring-framework/spring-core/…@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
时,SpringMVC 不使用 WebApplicationContext 来进行 Autowired,而是使用 CGLIB 来创建代理?这里有其他解释示例out