在运行时明确地获取一个bean实例

4
我有一个情况,我有一个bean(我们称之为A),它需要另一个bean(B)。
这个B是通过使用MethodInvokingFactoryBean类的静态方法检索到的。这个静态方法依赖于系统状态,并且在web应用程序加载后才能工作。
我只需要在运行时访问B(构造函数中没有交互)。如何配置A以自动装配bean B,并且只在A首次需要它时初始化?
在应用程序上下文中使用getBean是唯一的方法吗?
谢谢!
*编辑-添加了一些xmls :) *
这是bean B的定义。
<bean id="api" class="com.foo.API"/>
<bean id="B" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true">
        <property name="targetObject" ref="api"/>
        <property name="targetMethod" value="getFactory"/>
        <qualifier value="myQualifer"/>
</bean>

这是Bean A的定义。 <bean id="resources.someRESTResourceA" class="com.foo.MyRestResource"/> 我不能使用Autowire将B注入A,因为这会在A构造时初始化它(B)。
B的targetMethod只有在Web应用程序初始化后才能正常工作。我可以在A内部使用ApplicationContext.getBean("B"),但这不够优雅,并且在单元测试中会遇到问题,除非我执行以下操作(这也不是理想的解决方案):
public BInterface getB() {
 if  (b == null) {
 b = ApplicationContext.getBean("B");
}
return b;
}

1
如果您能够发布Spring上下文的示例以及示例bean代码,那么理解问题将会更加容易。 - Gary
添加了一些代码和 XML 文件。谢谢。 - TheGuyWhoCodes
大家好,我也曾为此苦恼。最终,我发现解决问题的方法非常简单:只需实现Spring的ApplicationContextAware接口,该接口强制您实现setApplicationContext方法,该方法由Spring调用。Spring将上下文实例放入其中。一旦您拥有它,您就可以使用appContext.getBean()轻松获取所需的bean。简单吧! - Lawrence
1个回答

1

你应该使用延迟初始化方式来初始化A Bean。

<bean id="A" class="demo.A" lazy-init="true">
  <property name="b" ref="B"/>
</bean>

当您需要使用getBean()方法时,仍然需要从Spring容器中检索bean A。通过ApplicationContextAware接口可以轻松访问它。

如果您将bean A自动装配到另一个bean中,并且在构建bean B之前检索该bean,则Spring容器将在将其作为属性注入到另一个bean时创建bean A。


Bean A 不能使用lazy init,因为它是在Web应用程序启动时创建的REST服务。 - TheGuyWhoCodes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接