ChatGPT解决这个技术问题 Extra ChatGPT

弹簧作用域代理bean

有人可以解释一下 spring @ScopedProxy 注释的用法吗?我认为它与会话范围的 bean 有关,但我不太确定是什么。

在我使用范围时,我使用了没有 @ScopedProxy 注释(或没有 aop 范围代理)的会话范围 bean,所以我非常确定如何正确使用它。

查看 the bean documentation。会话是 one of the scopes,但不是唯一一个。
@Gus,我知道范围,只是不确定范围代理如何发挥作用
在我看来,Section 3.4.4.5 很好地解释了作用域代理的作用。 -- 两个例子之间的部分是重要的部分。
是的,这解释了它,谢谢。如果您想为我接受的问题添加答案。

h
hagrawal

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>

那么当我使用@ScopedProxy注解时,会自动使用一个Proxy,这就是全部? ScopedProxy 的意思是 -> 不要按原样使用这个类,使用代理吗?
我正在使用 spring-web:4.3.3 并且看起来注释 @ScopedProxy 已替换为 @RequestScope 和其他。您可以在此处找到示例:logicbig.com/tutorials/spring-framework/spring-core/…
我们可以说,当使用符号 @Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS) 时,SpringMVC 不使用 WebApplicationContext 来进行 Autowired,而是使用 CGLIB 来创建代理?这里有其他解释示例out
可以使用 ApplicationContextAware 接口或方法注入来实现相同的功能吗?
B
Blue

在尝试了此处指定的各种不同选项和 spring 文档之后,由于某种原因,我发现 Spring MVC 在您使用 @Controller 注释并且您的 web 应用程序中有多个这样的控制器时会奇怪地自动装配控制器。将注解修改为@RestController (value="UniqueControllerv1"),问题解决。