弹簧范围代理豆

2022-08-31 10:21:28

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

在我对作用域的使用中,我使用了没有注释(或没有aop作用域代理)的会话作用域bean,所以我真的确定如何正确使用它。@ScopedProxy


答案 1

Spring docs的第3.4.4.5节很好地解释了它:

(请注意,以下“用户首选项”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 Session 范围的 bean 'userPreferences' 的引用。这里的突出点是“userManager”豆是一个单例...它将在每个容器中仅实例化一次并且其依赖项(在本例中只有一个,即“userPreferences”bean)也只会被注入(一次!

这意味着“userManager”将(从概念上讲)只在完全相同的“userPreferences”对象上运行,即它最初注入的对象。

当您将 HTTP 会话范围的 Bean 作为依赖项注入协作对象(通常)时,这不是您想要的。相反,我们想要的是每个容器一个“userManager”对象,然后,在HTTP会话的生存期内,我们希望查看并使用特定于所述HTTP会话的“userPreferences”对象

相反,你需要的是注入某种对象,该对象公开与UserPreferences类完全相同的公共接口(理想情况下是UserPreferences实例的对象),并且足够智能,能够从我们选择的任何底层范围机制(HTTP请求, 会话等)。然后,我们可以安全地将此代理对象注入“userManager”bean中,这将幸福地不知道它所持有的UserPreferences引用是代理

在我们的例子中,当一个UserManager实例调用依赖注入的UserPreferences对象上的方法时,它实际上将调用代理上的方法...然后,代理将关闭并从(在本例中为)HTTP 会话中获取真正的 UserPreferences 对象,并将方法调用委托给检索到的真实 UserPreferences 对象。

这就是为什么在将请求、会话和 globalSession 作用域的 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>

答案 2

在尝试了此处指定的各种不同选项和弹簧文档之后,由于某种原因,我已经弄清楚了Spring MVC,当您使用@Controller注释并且Web应用程序中有多个这样的控制器时,它会灵活地自动布线控制器。已将批注修改为@RestController(值=“UniqueControllerv1”),问题已解决。


推荐