【问题标题】:how does scoped proxy works internally in Spring作用域代理如何在 Spring 内部工作
【发布时间】:2016-08-12 07:03:13
【问题描述】:
考虑将原型作用域 bean 注入单例作用域 bean 的情况,
当我们尝试使用单例范围的 bean 访问原型范围的 bean 时,每次都返回相同的 bean,即在单例初始化时注入的 bean。
如果我们想在每次使用作用域代理时获取不同的实例。
我不明白这个作用域代理在后台是如何工作的,以及它如何神奇地为我们提供一个新实例,即使 bean 存在于单例中。
【问题讨论】:
标签:
spring
spring-mvc
proxy
javabeans
【解决方案1】:
来自 Spring 文档:
能够定义一个范围为 HTTP 请求或会话(或者实际上是您自己设计的自定义范围)的 bean 非常好,但是 Spring IoC 容器的主要增值之一是它管理只有对象(bean)的实例化,还有协作者(或依赖项)的连接。如果要将(例如)HTTP 请求范围 bean 注入另一个 bean,则需要注入 AOP 代理来代替范围 bean。也就是说,您需要注入一个代理对象,该对象公开与作用域对象相同的公共接口,但它足够聪明,能够从相关作用域(例如 HTTP 请求)和委托方法中检索真实的目标对象调用真实对象。
…
要创建这样的代理,您只需将一个子元素插入到作用域 bean 定义中(您可能还需要类路径中的 CGLIB 库,以便容器可以实现基于类的代理;您还需要使用附录 A,基于 XML 模式的配置)。那么,为什么在请求、会话、globalSession 和“在此处插入自定义范围”级别的 bean 定义中需要此元素?最好通过分解以下 bean 定义来解释原因(请注意,以下 'userPreferences' bean 定义目前是不完整的):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>