> For the complete documentation index, see [llms.txt](https://doc.shiker.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.shiker.tech/spring-he-xin-gong-neng/10.-fu-lu/10.2.-zi-ding-yi-xml-schema/10.2.2.-bian-ma-yi-ge-namespacehandler.md).

# 10.2.2. 编码一个NamespaceHandler

除了模式之外，我们还需要`NamespaceHandler`解析 Spring 在解析配置文件时遇到的这个特定命名空间的所有元素。对于这个例子， `NamespaceHandler`应该负责`myns:dateformat` 元素的解析。

`NamespaceHandler`接口具有三种方法：

* `init()`: 允许初始化 `NamespaceHandler` 并在使用处理程序之前由 Spring 调用。
* `BeanDefinition parse(Element, ParserContext)`：当 Spring 遇到顶级元素（未嵌套在 bean 定义或不同的命名空间内）时调用。此方法本身可以注册 bean 定义、返回 bean 定义或两者兼而有之。
* `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)`：当 Spring 遇到不同命名空间的属性或嵌套元素时调用。一个或多个 bean 定义的装饰（例如）与 [Spring 支持的范围](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-scopes)一起使用。我们首先突出一个简单的例子，不使用装饰，然后我们在一个更高级的例子中展示装饰。

尽管您可以为整个命名空间编写自己的`NamespaceHandler`代码（并因此提供解析命名空间中每个元素的代码），但通常情况下，Spring XML 配置文件中的每个顶级 XML 元素都会导致单个 bean 定义（在我们的例子中，单个`<myns:dateformat/>` 元素导致单个`SimpleDateFormat`bean 定义）。Spring 提供了许多支持这种场景的便利类。在以下示例中，我们使用`NamespaceHandlerSupport`该类：

```java
package org.springframework.samples.xml;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class MyNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        registerBeanDefinitionParser("dateformat", new SimpleDateFormatBeanDefinitionParser());
    }
}
```

您可能会注意到，此类中实际上并没有很多解析逻辑。事实上，`NamespaceHandlerSupport` 类有一个内置的委托概念。它支持注册任意数量的`BeanDefinitionParser`实例，当需要解析其名称空间中的元素时，它会委托给这些实例。这种干净的关注点分离让 `NamespaceHandler` 能够处理其命名空间中所有自定义元素的解析编排，同时委托 `BeanDefinitionParsers` 来完成 XML 解析的繁重工作。这意味着每个`BeanDefinitionParser`仅包含解析单个自定义元素的逻辑，正如我们在下一步中看到的那样。
