【问题标题】:Creating a network of objects from custom XML config with Spring使用 Spring 从自定义 XML 配置创建对象网络
【发布时间】:2017-08-31 10:30:28
【问题描述】:

我有一个自定义 XML 配置,定义了一种类似这样的网络

S1 ---- O1 ---- O2 ---- O3 ---- T1
 \
   +--- O4 ---- O5 ------------ T2
    \
S2---+- O6 --+- O7 ------------ T4
    /       /
S3-+       /
          /
S4 ------+

在哪里

  • S 是某种数据源,例如网络套接字
  • O 是处理数据的算子
  • T 是目标或数据接收器

这些元素用 xml 块表示,如下所示:

<source name="S1" address="ws://example/1" type="websocket" dataType="double" />

<operator name="O6" type="threshold">
    <input name="S1"/>
    <input name="S2"/>
    <input name="S3"/>
    <property name="threshold" value="10.34" />
    <property name="window" value="10.0" />
</operator>

<sink name="T1" type="database">
    <input name="O3"/>
</sink>

依赖项是构造函数参数。我的示例运算符 O6 将具有这样的构造函数:

class ThresholdOperator extends Operator<Boolean> {

    public ThresholdOperator(
        String name,              // "O6"
        List<DataSource> sources, // [S1, S2, S3]
        double threshold,         // 10.34
        double window) {          // 10.0
    ...

这个类可能有多个具有不同构造函数参数的实例。一个类可能有多个构造函数。基类的类型参数是输出类型。

type 属性决定了必须实例化的具体类。源的dataType 属性决定了应该注入哪种类型的转换器(这里是StringDouble)。

要创建实例,我需要找出一个依赖关系图并开始实例化对象,而我的图中没有其他对象作为依赖项(在本例中为源),然后我将创建仅依赖于在第一步等等。

所以我基本上会为我的特殊用例重新发明类似 Spring 的东西。在我的情况下,有没有办法利用 Spring 创建和连接对象?一个有点粗略的技巧是将我的 xml 配置转换为 beans.xml。但也许有更好的方法使用BeanFactory 等。还是可以直接创建 Spring 元模型?

我正在使用 Spring 4.3,但 Spring 5 的 RC 可能是一个选择,如果它有帮助的话。

【问题讨论】:

  • 我添加了另一种可能对您的情况有用的解决方案。查看我帖子的更新。
  • 您可能想看看apache-camel,因为您似乎为某些端点构建了一些处理路线和指令。

标签: java xml spring


【解决方案1】:

此处尚未提及的另一个替代方法是使用XSLT

这个想法是定义xsl,将您的特定域xml映射到spring beansxmlXSLT+XPath应该足以涵盖您的情况)。

然后,您可以使用 xsl 读取特定于域的 xmltransform 并将结果提供给 spring。

【讨论】:

    【解决方案2】:

    看看StaticApplicationContext。文档中说明它是:

    主要用于测试。

    ...但它是一个完整的应用程序上下文,支持编程 bean 注册。

    您可以读取特定于域的 xml 并在 StaticApplicationContext 中基于它定义 bean。

    This blog post 可以让您了解如何使用StaticApplicationContext 来定义带有引用和构造函数参数的bean。

    【讨论】:

    • 谢谢,StaticApplicationContext 正是我想要的。我建议您拆分您的答案(StaticApplicationContext,XSLT),以明确选择的解决方案是什么,并让其他人有机会分别为这两种方法投票。
    【解决方案3】:

    从文档中实例化对象的更简单方法是

    1. 创建一个 XML Schema 来描述您的数据格式并使用 JAXB 创建您的 Java 类
    2. 使用 JAXB 注释对现有 Java 类进行注释

    【讨论】:

    • 我已经在使用 JAXB,但是生成的对象结构离我的目标对象太远,由于 JAXB 的限制,我无法靠近。所以我需要一个额外的组装步骤,但无论如何我喜欢你的想法,因为它可能是更简单情况下的解决方案。
    • 您是否考虑过使用 XSLT 或 mapstruct 将输入转换为您需要的内容?
    【解决方案4】:

    “crud” hack 方法可能是更好的方法,但我建议您查看 Extensible XML authoring 方法,而不是手动将您的配置 xml 转换为 beans xml 文件。

    配置解析器,也称为 bean 定义解析器,允许您构建 bean 定义,最终将使用应用程序的 spring 上下文来实例化 bean。

    这也应该消除手动找出依赖层次结构和自己实例化对象的需要。

    希望它能回答你的问题。

    【讨论】:

    • 这是一个非常好的方法。但是,如果我理解正确,一个woule 仍然需要通常的 Spring XML 作为“容器”。所以我无法按原样使用外部 XML 文件,但可以轻松地将其转换为我的自定义 Spring XML 扩展格式。对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多