10.2.6. 更详细的例子

本节介绍一些更详细的自定义 XML 扩展示例。

在自定义元素中嵌套自定义元素

本节中的示例展示了如何编写满足以下配置目标所需的各种工件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:foo="http://www.foo.example/schema/component"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.foo.example/schema/component http://www.foo.example/schema/component/component.xsd">

    <foo:component id="bionic-family" name="Bionic-1">
        <foo:component name="Mother-1">
            <foo:component name="Karate-1"/>
            <foo:component name="Sport-1"/>
        </foo:component>
        <foo:component name="Rock-1"/>
    </foo:component>

</beans>

前面的配置将自定义扩展相互嵌套。 元素实际配置的类是 Component 类(如下一个示例所示)。请注意 Component 类如何不公开 Components 属性的 setter 方法。这使得通过使用 setter 注入来配置 Component 类的 bean 定义变得困难(或者说不可能)。以下清单显示了 Component 类::

此问题的典型解决方案是创建一个自定义FactoryBean来公开components属性的setter属性。以下清单显示了这样的自定义 FactoryBean

这很好用,但它向最终用户暴露了很多 Spring 管道。我们要做的是编写一个自定义扩展来隐藏所有这些 Spring 管道。如果我们坚持前面描述的步骤,我们首先创建 XSD 模式来定义我们的自定义标签的结构,如以下清单所示:

再次按照前面描述的过程,我们然后创建一个自定义NamespaceHandler

接下来是自定义BeanDefinitionParser。请记住,我们正在创建描述 ComponentFactoryBeanBeanDefinition 。以下清单显示了我们的自定义BeanDefinitionParser实现:

最后,需要通过修改META-INF/spring.handlersMETA-INF/spring.schemas文件将各种工件注册到 Spring XML 基础架构,如下所示:

“普通”元素的自定义属性

编写您自己的自定义解析器和相关的工件并不难。但是,有时这不是正确的做法。考虑一个场景,您需要将元数据添加到已经存在的 bean 定义中。在这种情况下,您当然不想编写自己的整个自定义扩展。相反,您只想向现有的 bean 定义元素添加一个附加属性。

再举一个例子,假设您为(它不知道的)访问集群 JCache的服务对象定义了一个 bean 定义,并且您希望确保命名的 JCache 实例在周围的集群中急切地启动。以下清单显示了这样的定义:

然后,当解析“jcache:cache-name”属性时,我们可以创建另一个 BeanDefinition。然后这个BeanDefinition为我们初始化命名的 JCache。我们还可以修改“checkingAccountService”的现有 BeanDefinition,使其依赖于这个新的 JCache 初始化 BeanDefinition。以下清单显示了我们的` JCacheInitializer:

现在我们可以转到自定义扩展。首先,我们需要编写描述自定义属性的 XSD 架构,如下所示:

接下来,我们需要创建关联的NamespaceHandler,如下:

接下来,我们需要创建解析器。请注意,在这种情况下,因为我们要解析 XML 属性,所以我们写的是 BeanDefinitionDecorator而不是BeanDefinitionParser。以下清单显示了我们的BeanDefinitionDecorator实现:

最后,我们需要通过修改META-INF/spring.handlersMETA-INF/spring.schemas文件将各种工件注册到 Spring XML 基础架构中,如下所示:

最后更新于

这有帮助吗?