好的,这是我的用例:

我有以下类,每个类都封装了下一个类的实例。所以:

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>

10-07 19:31
查看更多