好的,这是我的用例:
我有以下类,每个类都封装了下一个类的实例。所以:
A-> B-> C-> D
例如:在A类中,我有B类的实例,在B类中,我有C的实例,依此类推。
好吧,我正在尝试将loading \ initialization \ injection逻辑转换为混合Spring系统。通常的想法是B,C和D或多或少需要为ApplicationContextAware
。我的意思是说,他们实际上不会实现该接口,而是需要ApplicationContext
作为构造函数参数。这样,在混合方法(开发人员不使用Spring初始化实例)中,它们必须至少传递ApplicationContext
,以便可以连接其他bean。问题是,为了让Spring容器加载Bean,我现在必须在XML中传递ApplicationContext
。但是据我所知,没有很好的方法可以做到这一点。
我尝试过这样的事情:
public class ApplicationContextPlaceholder implements ApplicationContextAware {
private ApplicationContext _applicationContext;
public void setApplicationContext( final ApplicationContext applicationContext ) throws BeansException {
_applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return _applicationContext;
}
}
<bean id="a" class="com.company.A">
<constructor-arg>
<bean id="applicationContext" class="com.company.ApplicationContextPlaceholder" />
</constructor-arg>
</bean>
但这显然没有任何意义,因为
ApplicationContextPlaceholder
并不是真正的ApplicationContext
。我也一直在寻找引用XML内部上下文的方法,但是我什么也没找到。有谁知道这种问题的优雅解决方案?
编辑#1:
我在考虑这个问题,我还可以实现
ApplicationContextPlaceholder
并实现ApplicationContext
并只委托给注入的上下文,然后我想到也许这已经在Spring中了……但是据我所知告诉,不。编辑#2:
每个类都需要一个
ApplicationContext
的原因是,如果开发人员希望重写链中的一个类(例如,出于争论,请使用C)。在这种情况下,C的子类仍然需要通过Spring加载D。 最佳答案
除非类提供其他管道功能,否则应避免暴露ApplicationContext
。引用Spring参考:in general you should avoid it, because it couples the code to Spring and does not follow the Inversion of Control style
。
如果您要提供其他功能(例如,可能是使用ApplicationContext
来组装对象的工厂类),则由于您的功能已经与Spring绑定,因此最好实施ApplicationContextAware
。
如果您考虑了dependency injection替代方法并决定将ApplicationContext
注入到bean中,则您的ApplicationContextPlaceholder
类(我会尽量避免使用Placeholder
前缀以避免与Spring property placeholders混淆)当然是一个解决方案。 (因为这是您自己的类,所以为什么不扩展ApplicationObjectSupport
以获得更多功能。)
此类需要在您的配置中定义和初始化,例如:
<bean id="appCtxHolder" class="ApplicationContextHolder" />
因为
ApplicationContextHolder
实现了ApplicationContextAware
,所以Spring会在初始化时将ApplicationContext
注入到appCtxHolder
中。您可以将其用于构造函数注入,例如:<bean id="a" class="com.company.A">
<constructor-arg>
<bean factory-bean="appCtxHolder" factory-method="getApplicationContext" />
</constructor-arg>
</bean>