Spring的自定义Schema是如何解析生效的

作者:CQITer小编 时间:2018-07-09 21:51

字号
开发者盛宴来袭!7月28日51CTO首届开发者大赛决赛带来技术创新分享

随着 Spring Boot 的日渐流行,应用里的大部分配置都被隐藏了起来,我们仅需要关心真正的业务内容, Controller, Service, Repository,拿起键盘就是一通业务代码的Coding,具体的 Component Scan,View,PlaceHolder ... 都可以抛在脑后。但其实这种零配置在 Java 应用开发中,还真不太久。 「由奢入俭难」,不少开发者都经历过 Spring XML 配置的冗长,再回到这种配置确实不好受。

但有些时候,由于配置的内容在 Spring Boot这种零配置中并不能很好的实现,就需要我们仍使用 XML 的配置形式,然后再 ImportSource进来。或者一些项目受环境等影响,未使用Boot进行开发,此时也需要对配置有一定的了解。

那这次让我们往回看一些,看看在 XML 配置中,一些自定义的 Schema 内容,是如何融合到 Spring 中进行配置的。例如:

Spring data es

Spring data es

dubbo

Spring的自定义Schema是如何解析生效的

还有许多这样的例子,我们不再一一罗列。但通过上述两个图,我们发现一个共同的特点:

都是通过schemaLocation将对应的schema引入

在对应的beans元素中增加更具体的自定义配置

那这些自定义的配置,是在什么时候工作的呢?如何校验是否配置正确?

我们来看 Spring 中包含一个名为 spring.handlers的文件,所有的自定义扩展,都是通过这个文件生效的。spring 官方的aop, tx 也都是这个原理。

这个文件在哪呢?

Spring的自定义Schema是如何解析生效的

如上图所示,是META-INF/spring.handlers。文件内容也超级简单:

http\://www.springframework.org/schema/data/elasticsearch=org.springframework.data.elasticsearch.config.ElasticsearchNamespaceHandler

前面是各个schema前缀,后面是schema 对应的解析类。这个spring.handlers文件是什么时候加载的呢?

这个也是发生在解析自定义配置文件过程中,有一个resolve的过程,此时会将当前classLoader对应的所有包含spring.handlers文件加载过来。

我们再来看这个解析类,内容如下:

 public class ElasticsearchNamespaceHandler extends NamespaceHandlerSupport { 

     public ElasticsearchNamespaceHandler() { 

     } 

  

     public void init() { 

         RepositoryConfigurationExtension extension = new ElasticsearchRepositoryConfigExtension(); 

         RepositoryBeanDefinitionParser parser = new RepositoryBeanDefinitionParser(extension); 

         this.registerBeanDefinitionParser("repositories", parser); 

         this.registerBeanDefinitionParser("node-client", new NodeClientBeanDefinitionParser()); 

        this.registerBeanDefinitionParser("transport-client", new TransportClientBeanDefinitionParser()); 

    } 

首先是继承自NamesapceHandlerSupport

然后在重写的init方法中注册了一系列的parser,每个parser对应一个字符串,就是我们在xml配置文件是使用的自定义内容,比如上面的es的配置

<elasticsearch:transport-client id="client" 

   cluster-nodes="192.168.73.186:9300" cluster 

这里的配置最终就会通过 TransportClientBeanDefinitionParser 来进行解析

而上面提到的各个parser,在init方法中,保存在了一个Map中

private final Map<String, BeanDefinitionParser> parsers = new HashMap(); 

所谓注册parser,就是在向这个parsers的map进行put操作。

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>Spring Schema Java
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接