spring scoped代理bean

时间:2013-01-17 02:37:29

标签: java spring proxy

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

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

2 个答案:

答案 0 :(得分:229)

Section 3.4.4.5春季文档解释得非常好:

(请注意,以下'userPreferences'bean定义不完整):

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

<bean id="userManager" class="com.foo.UserManager">
    <property name="userPreferences" ref="userPreferences"/>
</bean>

从上面的配置中可以看出,单例bean'userManager'被注入了对HTTP Session-scoped bean'userPreferences'的引用。这里的重点是 'userManager'bean是一个单例 ...它将 每个容器实例化一次 < / strong>, 及其依赖项 (在这种情况下只有一个,'userPreferences'bean) 也只会被注入(一次!)< / EM>

这意味着'userManager'将(在概念上)仅对完全相同的'userPreferences'对象进行操作,即最初注入的对象。

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

而你需要的是注入某种类型的对象,它暴露与UserPreferences类完全相同的公共接口(理想情况下是一个UserPreferences实例的对象),并且足够聪明,可以关闭并获取真正的UserPreferences对象来自我们选择的任何底层作用域机制(HTTP请求,会话等)。然后我们可以安全地将这个代理对象注入到'userManager'bean中,该bean很幸运地没有意识到它所持有的UserPreferences引用是 代理

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

这就是为什么在将request-,session-和globalSession-scoped 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>

答案 1 :(得分:0)

尝试了这里和spring文档中指定的各种不同选项后,由于某种原因,我弄清楚了Spring MVC在使用@Controller注释并且在webapp中有多个这样的控制器时会自动装配控制器。将注释修改为@RestController(value =“ UniqueControllerv1”),问题已解决。