gpt4 book ai didi

spring - 为引用 session bean/原型(prototype) bean 的单例 bean 创建了多少个实例

转载 作者:IT老高 更新时间:2023-10-28 13:47:32 28 4
gpt4 key购买 nike

我对下面提到的场景中使用Spring Framework时会创建的实例数量有疑问:

bean配置是这样的

<bean id="a" class="A">
<property name="b" ref="b"/>
</bean>

<bean id="b" class="B" scope="session"/> or

<bean id="b" class="B" scope="prototype"/>

默认情况下,bean "a"有 singleton scope .所以有一个单例 bean 引用具有 session 范围或原型(prototype)范围的 bean。

在这种情况下,如果有 2 个同时向应用程序发出请求,那么将创建多少个 A 实例和多少个 B 实例?

如果有人能解释这是如何工作的,那将会有很大帮助。

谢谢,
迪维亚

最佳答案

单例范围

当 bean 是 singleton ,将只管理 bean 的一个共享实例,并且所有对具有与该 bean 定义匹配的 id 或 ids 的 bean 的请求将导致 Spring 容器返回该特定 bean 实例。

换句话说,当你定义一个 bean 定义并且它的作用域为 singleton 时。 ,然后是 Spring IoC containercreate exactly one instance of the object由那个 bean 定义定义。该单个实例将存储在此类单例 bean 的缓存中,并且对该命名 bean 的所有后续请求和引用都将导致返回缓存对象。

session 范围

有了上面的 bean 定义,Spring 容器将为 lifetime of a single HTTP Session 创建一个全新的 bean 实例。 .

根据 Spring 框架引用,在需要将“lives longer”(在这种情况下是单例 bean)中的另一个类注入(inject)另一个具有相对较短生命周期的类( session 作用域 bean)的情况下,需要遵循不同的方法)。但是,原型(prototype)和单例范围的方法不同。

在您的 XML 中,我们想要的是 singletonBean 实例应该只实例化一次,并且应该注入(inject) sessionBean。但由于 sessionBean是 session 范围的(这意味着它应该为每个 session 重新实例化),配置不明确(因为依赖项是在实例化时设置的, session 范围的值也可以稍后更改)。

因此,它不是注入(inject)该类,而是注入(inject)一个代理,该代理公开与 sessionBean 完全相同的公共(public)接口(interface)。容器将这个代理对象注入(inject)到 singletonBean bean 中,它不知道这个 sessionBean 引用是一个代理。它通过在 sessionBean 中写入此标记来指定:

<aop:scoped-proxy/>

XML 配置:
<bean name="singletonBean" class="somepkg.SingletonBean">
<property name="someProperty" ref="sessionBean"/>
</bean>

<bean name="sessionBean" class="somepkg.SessionBean" scope="session">
<aop:scoped-proxy/>
</bean>

singletonBean实例调用依赖注入(inject)的 sessionBean 对象上的方法,它实际上是调用代理上的方法。然后代理从(在本例中)HTTP Session 获取真正的 sessionBean 对象,并将方法调用委托(delegate)给检索到的真实 sessionBean 对象。

另请引用 this了解更多信息。

具有原型(prototype) bean 依赖关系的单例 bean

查找方法注入(inject)

当您使用 singleton-scoped依赖于 prototype beans 的 bean ,请注意依赖项在实例化时解决。因此,如果你依赖注入(inject)一个 prototype-scoped bean 转换为单例范围的 bean,实例化一个新的原型(prototype) bean,然后将依赖注入(inject)到单例 bean 中。原型(prototype)实例是唯一提供给单例作用域 bean 的实例。

但是,假设您希望单例范围的 bean 在运行时重复获取原型(prototype)范围的 bean 的新实例。你不能将原型(prototype)范围的 bean 依赖注入(inject)到你的单例 bean 中,因为注入(inject)只发生一次,当 Spring 容器正在实例化单例 bean 并解析和注入(inject)它的依赖项时。
<!-- a stateful bean deployed as a prototype (non-singleton) -->
<bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
<!-- inject dependencies here as required -->
</bean>

<!-- commandProcessor uses statefulCommandHelper -->
<bean id="commandManager" class="fiona.apple.CommandManager">
<lookup-method name="createCommand" bean="command"/>
</bean>
Lookup method注入(inject)是容器的能力 override methods on container托管 bean,返回容器中另一个命名 bean 的查找结果。 lookup通常涉及 prototype bean如上一节所述的场景。 Spring 框架通过使用来自 CGLIB library 的字节码生成来实现此方法注入(inject)。动态生成覆盖该方法的子类。

引用 lookup method injection .

Follow有关更详细的示例和信息。

关于spring - 为引用 session bean/原型(prototype) bean 的单例 bean 创建了多少个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25000406/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com