我怀疑使用Spring时将在下面提到的场景中创建的实例数量:
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,它引用了一个具有会话范围或原型范围的bean。
在这种情况下,如果同时有2个应用程序请求,那么将创建多少个A实例以及将创建多少个B实例?
如果有人可以解释这是如何起作用的话会有很大的帮助吗?
谢谢, 迪夫亚
答案 0 :(得分:36)
单身范围
当bean是singleton
时,将只管理bean的一个共享实例,并且对具有与该bean定义匹配的id或id的bean的所有请求将导致返回一个特定的bean实例Spring容器。
换句话说,当你定义一个bean定义并且它的范围是singleton
时,那个bean定义所定义的Spring IoC container
将create exactly one instance of the object
。此单个实例将存储在此类单例bean的缓存中,并且该命名bean的所有后续请求和引用将导致返回缓存对象。
会话范围
通过上面的bean定义,Spring容器将为lifetime of a single HTTP Session
创建一个全新的bean实例。
根据Spring框架参考,在需要向另一个具有相对较短寿命的类注入“lives longer
”(在这种情况下为单例bean)的类的情况下,需要遵循不同的方法。 (会话范围的bean)。原型和方法的方法不同。单身范围虽然。
在XML中,我们想要的是singletonBean实例只应实例化一次,并且应该使用sessionBean注入。但由于sessionBean
是会话范围的(这意味着它应该为每个会话重新实例化),配置是不明确的(因为依赖关系是在实例化时设置的,会话范围的值也可以在以后更改)。 / p>
因此,不是使用该类注入,而是注入一个代理,该代理公开与sessionBean完全相同的公共接口。容器将此代理对象注入singletonBean bean,该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
实例在依赖注入的sessionBean对象上调用方法时,它实际上是在代理上调用方法。然后,代理从(在这种情况下)HTTP会话中获取真实的sessionBean对象,并将方法调用委托给检索到的真实sessionBean对象。
另请参阅this了解更多信息。
具有原型bean依赖关系的单例bean
查找方法注入
当您在singleton-scoped
上使用具有依赖关系的prototype beans
bean时,请注意在实例化时解析依赖关系。因此,如果依赖项将prototype-scoped
bean注入到单例范围的bean中,则会实例化一个新的原型bean,然后将依赖注入到单例bean中。原型实例是唯一提供给单例范围bean的实例。
但是,假设您希望单例范围的bean在运行时重复获取原型范围的bean的新实例。您不能将原型范围的bean依赖注入到您的单例bean中,因为当Spring容器实例化单例bean并解析并注入其依赖项时,该注入只发生一次。
<!-- 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
注入是容器到override methods on container
托管bean的能力,用于返回容器中另一个命名bean的查找结果。 lookup
通常涉及prototype bean
,如上一节中所述的方案。 Spring Framework通过使用CGLIB library
中的字节码生成来实现此方法注入,以动态生成覆盖该方法的子类。
Follow了解更详细的示例和信息。
答案 1 :(得分:0)
如果我们使用问题中提到的方式,春天IOC将创建始终返回与singleton相同的对象,为了在singleton中注入原型bean我们有两种方式
1)查找方法注入
2)Scoped Proxies
查看更多详情here