好的,这是我的用例:
我有以下类,每个类都封装了下一个实例。所以:
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
的原因是,如果dev希望覆盖链中的一个类(例如,为了参数而使用C)。在这种情况下,C的子类仍然需要通过Spring加载D.
答案 0 :(得分:1)
除非某个类提供额外的管道功能,否则应避免暴露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
组装对象的工厂类),那么实施ApplicationContextAware
是谨慎的,因为您的功能已经与Spring绑定。
如果你已经考虑了dependency injection替代方案,并决定在你的bean中注入ApplicationContext
,那么你的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>
答案 1 :(得分:0)
ApplicationContextPlaceholder
可以让一切都变得静止。在这种情况下,您不需要传递ApplicationContext
,当API请求某个bean时,您可以检查它是否为null,如果是,则使用来自{{ApplicationContext
的{{1}}加载它。 1}}。这是假设基于setter的注入,如果你正在构建基于构造函数,你也可以在构造函数中初始化bean。