前言

Spring 作为 Java 世界非官方标准框架,任何一个中间件想要得到良好的发展,必须完美支持 Spring 的各种特性,即:无缝融入 Spring。

Apollo 作为分布式配置中心,服务于 Java 应用程序,Java 应用程序可以通过 Apollo 提供的 Client 获取远程配置信息。而如何将这个 Client 高度融合到用户的应用程序中呢?

这就需要针对 Spring 提供给我们的接口进行扩展。

在之前的文章中,已经大致聊过 Spring 的一些扩展接口:深入理解Spring 之 Spring 进阶开发必知必会 之 Spring 扩展接口

而想融入 Spring,首先得找到入口,然后才能注册相关的类进行自己系统的初始化。

所以,如何找到并处理入口成了一门学问,我们今天看看 apollo 如何处理的。

第一种入口:XML

XML 是传统 Java 项目的配置文件,特别是 Spring MVC 项目。虽然现在都是使用的自动化配置,但仍然有一些遗留项目使用 XML,因此,支持 XML 是大部分中间件的必须工作。

支持 XML 需要准守 Spring 的几个约定:

  1. 继承 NamespaceHandlerSupport 抽象类,重写 init 方法,调用 registerBeanDefinitionParser 方法,并传入自己继承的 AbstractSingleBeanDefinitionParser 子类用于解析标签,重写他的 getBeanClass 方法,返回一个 Bean,用于注册相关的 Bean。
  2. classpath 下创建 META-INF 目录,创建 spring.handlers 文件,将 xml 配置中的 URL 指向 NamespaceHandlerSupport
  3. META-INF 目录下,创建 apollo-1.0.0.xsd xsd 文件,用于解释自定义标签。
  4. META-INF 目录下,继续创建 spring.schemas 文件,将 xml 配置中的 xsd URL 指向 xsd 文件。

如果你的 xml 配置中,引用了 apollo 的标签,Spring 将会根据 xml 中的 URL 找到 spring.handlers 中的 NamespaceHandlerSupport 类,并对标签进行解析。也会从 getBeanClass 得到一个设置的 bean,在这个 bean 里,做了 apollo 关键类的注册。

第二种入口:@Import 注解

相对于基于XML的配置,基于Java的配置是目前比较流行的方式。

@Import 注解的使用方式:

  1. 定义一个自己的启动注解。并标注 @import 注解, 其实就是 xml 中的 import 标签,在该注解中,可以配置一个类,这个类就会注册进 Spring 的容器,成为 Bean,你就可以在这个 bean 里做文章。

    在 apollo 中,使用方式如下:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented
@Import(ApolloConfigRegistrar.class)
public @interface EnableApolloConfig {
String[] value() default {ConfigConsts.NAMESPACE_APPLICATION};
int order() default Ordered.LOWEST_PRECEDENCE;
}
  1. 从上面可以看出 ApolloConfigRegistrar 类是 apollo 注册进的 bean。这个 bean 用于处理 @EnableApolloConfig 注解,同时注册 apollo 关键 Bean 到 Spring 容器中。

  2. 用户只需在 Spring 系统中的某个类上,标注 @EnableApolloConfig ,就可以通过 Spring 的方式(自动更新,注解等)使用 apollo 功能。

第三种入口:SpringBoot Starter

目前最流行的框架就是 Spring Boot ,兼容 SpringBoot 是一个大趋势。

Spring Boot 提供 spring-boot-autoconfigure 让第三方框架兼容 Boot,称之为 starter。

创建一个 starter 需要遵守几个约定:

  1. maven 引入 spring-boot-autoconfigure artifact.
  2. 创建一个类,实现ApplicationContextInitializer 接口,重写 initialize 方法,该方法在容器初始化的时候调用。
  3. META-INF 创建 spring.factories 文件,Boot 启动时会自动扫描这个文件。需要在这个文件中写入一个步骤 2 创建的类,类似 org.springframework.context.ApplicationContextInitializer=\com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer。这个类的作用是提前(容器初始化前)加载关键配置到 Spring 环境。
  4. spring.factories 文件中,还需要让 boot 的 EnableAutoConfiguration 自动配置类指向一个自定义类。这是 SpringBoot starter 的关键,例如:org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ctrip.framework.apollo.spring.boot.ApolloAutoConfiguration。ApolloAutoConfiguration 就会加入的 apollo 的配置 bean 中。你可以在这个配置 bean 中,创建一个关键 bean ,用于处理系统相关的初始化类。例如 apollo 的方式:
@Configuration
@ConditionalOnProperty(PropertySourcesConstants.APOLLO_BOOTSTRAP_ENABLED)
@ConditionalOnMissingBean(PropertySourcesProcessor.class)// 当Spring Context中不存在该Bean时
public class ApolloAutoConfiguration {
@Bean
public ConfigPropertySourcesProcessor configPropertySourcesProcessor() {
return new ConfigPropertySourcesProcessor();
}
}

在 apollo 中,ConfigPropertySourcesProcessor 就是用来注册系统关键 bean 的。

总结

本文重点介绍了 3 种入口:

  1. XML 方式,通过在 getBeanClass 方法返回系统关键 Bean。
  2. @Import 注解,通过在注解中定义 Bean,然后在该 Bean 中处理。
  3. SpringBoot Starter 方式,通过 spring.factories 文件中定义自动配置类,可以注册系统关键 bean。

在以后的开发中,如果想融入 Spring,就可以通过这 3 种方式自行处理。

Apollo 1 融合 Spring 的三个入口的更多相关文章

  1. SpringBoot入门(三)——入口类解析

    本文来自网易云社区 上一篇介绍了起步依赖,这篇我们先来看下SpringBoot项目是如何启动的. 入口类 再次观察工程的Maven配置文件,可以看到工程的默认打包方式是jar格式的. <pack ...

  2. Spring的三种通过XML实现DataSource注入方式

    Spring的三种通过XML实现DataSource注入方式: 1.使用Spring自带的DriverManagerDataSource 2.使用DBCP连接池 3.使用Tomcat提供的JNDI

  3. spring ioc三种注入方式

    spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...

  4. Redis实战之征服 Redis + Jedis + Spring (三)

    一开始以为Spring下操作哈希表,列表,真就是那么土.恍惚间发现“stringRedisTemplate.opsForList()”的强大,抓紧时间恶补下. 通过spring-data-redis完 ...

  5. 征服 Redis + Jedis + Spring (三)—— 列表操作【转】

    一开始以为Spring下操作哈希表,列表,真就是那么土.恍惚间发现“stringRedisTemplate.opsForList()”的强大,抓紧时间恶补下. 相关链接: 征服 Redis 征服 Re ...

  6. Spring第三天

    Spring第三天 整体课程安排(3天+2天): 第一天:Spring框架入门.IoC控制反转的配置管理.Spring Web集成.Spring Junit集成. 第二天:Spring AOP面向切面 ...

  7. Spring中三种配置Bean的方式

    Spring中三种配置Bean的方式分别是: 基于XML的配置方式 基于注解的配置方式 基于Java类的配置方式 一.基于XML的配置 这个很简单,所以如何使用就略掉. 二.基于注解的配置 Sprin ...

  8. Spring中三个重要概念 IOC AOP Bean

    Spring中三个重要概念 IOC AOP Bean 首先讲解一下Spring框架,以及为什么要使用Spring 框架? spring 是一个很好的容器框架, 是轻量级的IoC和AOP的容器框架,主要 ...

  9. 相机IMU融合四部曲(三):MSF详细解读与使用

    相机IMU融合四部曲(三):MSF详细解读与使用 极品巧克力 前言 通过前两篇文章,<D-LG-EKF详细解读>和<误差状态四元数详细解读>,已经把相机和IMU融合的理论全部都 ...

随机推荐

  1. SIFT算法

     备注:源代码还未理解,所以未附上——下周任务 一.SIFT算法 1.算法简介 尺度不变特征转换即SIFT (Scale-invariant feature transform)是一种计算机视觉的算法 ...

  2. canvas画圆环

    <!DOCTYPE html><html> <head> <title> </title> <meta http-equiv=&quo ...

  3. 2017-2018-1 20155205 嵌入式C语言——时钟

    2017-2018-1 20155205 嵌入式C语言--时钟 题目要求 基础知识 插入位(以分钟为例) 提取位(以分钟为例) 在提取分钟时,运用到了位运算,位运算有以下规律: &0 --&g ...

  4. ScriptOJ-safeGet#99

    const safeGet = (data, path) => { if(!path) return undefined; const pathArr = path.split('.'); le ...

  5. 《分布式Java应用与实践》—— 后面两章

    failover? NAT IP-tunneling DSR vrrp gossip 什么是2PC? 什么是3PC? 什么是Pasox? sna? dal? mpi?

  6. 使用Ansible实现数据中心自动化运维管理

    长久以来,IT 运维在企业内部一直是个耗人耗力的事情.随着虚拟化的大量应用.私有云.容器的不断普及,数据中心内部的压力愈发增加.传统的自动化工具,往往是面向于数据中心特定的一类对象,例如操作系统.虚拟 ...

  7. vue 项目记录.路飞学城(一)

    前情提要: 通过vue 搭建路飞学城记录  一:项目分析 二:项目搭建 1:创建项目 vue init webpack luffy 2:初始化项目 清除默认的HelloWorld.vue组件和APP. ...

  8. Origin的使用问题集锦

    在空间上看见同学转的一篇关于学术研究的文章,由于不常常上空间,更别说在上面看一些好的文章,所以特意将那篇文章整理到自己的博客中,方便以后做科研的时候能够用到,原文出处:http://user.qzon ...

  9. EJB3与JPA的关系

    转载自http://www.cnblogs.com/o-andy-o/archive/2012/04/17/2453537.html JPA是基于Java持久化的解决方案,主要是为了解决ORM框架的差 ...

  10. 橙色优学:2019年设计行业怎么样?UI设计行业前景分析

    互联网的飞速发展带动了UI行业的火爆,成为时下最热门的高新技术行业.UI设计区别于传统的平面设计,更加注重界面.交互.体验等方面,这使UI设计变为了高薪的行业,对设计师的技能要求也就变得更加严格. 自 ...