java - 鸡和蛋 Spring Bean 绑定(bind)

标签 java spring inversion-of-control

好的,这是我的用例:

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

A -> B -> C -> D

例如:在 A 类中,我有一个 B 类的实例,在 B 类中我有一个 C 类的实例,依此类推。

嗯,我正在尝试将加载\初始化\注入(inject)逻辑转换为混合 Spring 系统。一般想法是 B、C 和 D 需要或多或少为 ApplicationContextAware 。我的意思是,他们实际上不会实现该接口(interface),而是需要 ApplicationContext作为构造函数参数。这样,在混合方法中(开发人员不使用 Spring 来初始化实例),他们必须至少传入 ApplicationContext这样就可以连接额外的bean。问题是,为了让 Spring 容器加载 bean,我现在必须传入 ApplicationContext在 XML 中。但据我所知,没有什么好的方法可以做到这一点。

我尝试过这样的事情:

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然后委托(delegate)给注入(inject)的上下文,然后我突然想到,也许,只是也许这已经在 Spring 中了……但据我所知,没有。

编辑#2:

每个类(class)需要 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 来组装对象的工厂类),那么谨慎的做法是实现 ApplicationContextAware,因为您的功能已经与 Spring 绑定(bind)在一起。

如果您考虑过您的dependency injection替代方案并决定在您的 bean 中注入(inject) ApplicationContext ,您的 ApplicationContextPlaceholder 类(我会远离 Placeholder 前缀以避免与 Spring property placeholders 产生任何混淆)当然是一个解决方案。 (既然它是您自己的类,为什么不扩展 ApplicationObjectSupport 以获得额外的功能。)

此类需要在您的配置中定义和初始化,例如:

<bean id="appCtxHolder" class="ApplicationContextHolder" />

由于 ApplicationContextHolder 实现了 ApplicationContextAware,Spring 在初始化时会将 ApplicationContext 注入(inject)到 appCtxHolder 中。您可以将它用于构造函数注入(inject),例如:

<bean id="a" class="com.company.A">
    <constructor-arg>
        <bean factory-bean="appCtxHolder" factory-method="getApplicationContext" />
    </constructor-arg>
</bean>

关于java - 鸡和蛋 Spring Bean 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8045045/

相关文章:

c# - IoC、工厂和构造函数参数

java - 应用程序服务器关闭后立即关闭所有 quartz 作业?

java - 客户端在监听服务器时主动等待

java - Android:是否可以下载Android自定义View的类(它是LinearLayout的扩展)并在运行时实例化它?

java - 创建 EnityManagerFactory 时出现 NullPointerException

c# - 通过 SimpleInjector 注册单例并返回相同的实例,对于它实现的不同接口(interface)

c# - 模拟数据访问器

java - 如何将对象从一个 case 语句传递到另一个 case 语句

Spring 表达式语言 (SpEL) 不适用于 JPA/hibernate 实体

java - 管理 JMS 消息到多个服务器的传递