【问题标题】:Accessing legacy out-of-container instantiated objects from Spring beans从 Spring bean 访问遗留的容器外实例化对象
【发布时间】:2010-05-19 17:34:14
【问题描述】:

我们有一个遗留系统,其中使用类似服务定位器的东西来实例化和提供所有服务对象:

class ServiceLocator {

    ServiceA serviceA;
    ServiceB serviceB;

    public ServiceLocator () {
        serviceA = ...;
        serviceB = ...;
    }

    public ServiceA getServiceA() {
        return serviceA;
    }

    public ServiceB getServiceB() {
        return serviceB;
    }
}

(想象一下还有 70 个字段和吸气剂...)

然后这个对象从一个类传递到另一个类以提供对服务对象的访问。

为现有代码更改此设计超出了项目的范围,但至少不会让事情变得更糟,我们想引入 Spring 以逐步实例化 future 服务,其中 DI 类似于Introducing an IoC Container to Legacy Code.

与上述情况相比,我们已经知道如何从遗留代码中访问 spring 创建的 spring bean 对象。我们的问题是我们计划使用 spring 创建的对象,这些对象需要在 spring 上下文之外创建的任何服务对象。

我们想出了以下解决方案:

为ServiceLocator创建一个静态访问器并在构造函数中设置,加载spring应用上下文对象。在 Spring 配置中,使用 Spring 参考中第 3.3.2.2 节中所述的静态访问器为 ServiceLocator 创建一个 bean:

<bean id="serviceLocator" 
  class="ServiceLocator"
  factory-method="getInstance"/>

如第 3.3.2.3 节所述,使用“实例工厂方法”为每个服务创建另一个 bean:

<bean id="serviceA"
  factory-bean="serviceLocator"
  factory-method="getServiceA"/>

创建引用这些“虚拟 bean”的其他 bean。

我想这会起作用,但会产生很多非常不必要的伪配置。我宁愿是这样的:

“如果引用了一个 bean 并且该 bean 没有显式定义,则在 ServiceLocator 类中搜索具有所需签名和名称的方法并使用此对象。”

有可能吗? spring bean 实例化过程中是否有任何我不知道并且可以在这里使用的入口点?我可以通过子类化 spring 应用程序上下文类来做到这一点吗?

任何帮助将不胜感激!

【问题讨论】:

    标签: spring dependency-injection inversion-of-control


    【解决方案1】:

    您可以定义一个BeanFactoryPostProcessor 来使用来自ServiceLocator 的bean 填充您的应用程序上下文。

    BeanFactoryPostProcessor 中,使用beanFactory.registerSingleton(...) 添加完全实例化的bean,或使用((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(...) 添加定义(请注意,某些应用程序上下文可能未实现BeanDefinitionRegistry,尽管所有典型上下文都实现了它)。

    【讨论】:

    • thx axtavt 你的建议看起来比我最初的想法要好得多,我会研究一下!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2012-11-08
    相关资源
    最近更新 更多