Spring范围的代理bean
有人可以解释Spring @ScopedProxy
注释的用法吗? 我认为这与会话范围的bean有关,但我不太确定。
在我使用范围时,我使用了没有@ScopedProxy
注解(或没有范围代理)的会话范围的bean,所以我确定如何正确使用它。
春季文档第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>
从上面的configuration中可以看出,单身bean'userManager'正在注入HTTP会话范围的bean'userPreferences'的引用。 这里的要点是'userManager'bean是一个单独的 …它将被实例化每个容器一次 , 它的依赖关系 (在这种情况下,只有一个,'userPreferences'的bean) 也将只被注入(一次! ) 。
这意味着'用户pipe理器'将(在概念上)只能在完全相同的'userPreferences'对象上运行,即它最初注入的对象。
当您将HTTP会话范围的bean作为dependency injection到协作对象(通常)时,这不是您想要的。 相反, 我们需要的是每个容器都有一个“userManager”对象 ,然后, 在HTTP Session的生命周期中,我们希望看到并使用特定于所述HTTP Session的“userPreferences”对象 。
相反,您需要的是注入某种types的对象,以公开与UserPreferences类完全相同的公共接口(理想情况下是一个UserPreferences实例的对象),并且足够聪明以便能够取出真正的UserPreferences对象来自我们select的底层范围机制(HTTP请求,会话等)。 然后,我们可以安全地将这个代理对象注入到'userManager'bean中,这将很幸福地意识到它所持有的UserPreferences引用是一个代理 。
在我们的例子中, 当一个UserManager实例在dependency injection的UserPreferences对象上调用一个方法时,它实际上会调用一个代理上的方法 …然后,代理将closures并获取真实的UserPreferences对象(在这种情况下) HTTP会话,并将方法调用委托给检索到的实际UserPreferences对象。
这就是为什么在将request-,session-和globalSession范围的bean注入到协作对象时,您需要以下正确且完整的configuration:
<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>