撸了一个简易的配置中心,顺带整合到了SpringCloud( 三 )


说的简单点就是用来定位到(也就是获取的意思)项目启动所需要的属性信息 。同时要注意到括号内的 可能是远程 告诉我们一个很重要的信息 , 那就是获取的配置信息不仅仅可以存在本地,而且还可以存在远程 。
远程?作者这里就差直接告诉你可以从配置中心获取了 。。
所以从这个注释就可以发现,原来PropertySourceLocator就是起到在SpringCloud环境下从配置中心获取配置的作用 。
PropertySourceLocator是一个接口 , 所以只要不同的配置中心实现这个接口,那么不同的配置中心就可以整合到了SpringCloud , 从而实现从配置中心加载配置属性到Spring环境中了 。
2、如何实现注入到Bean中的属性动态刷新?【撸了一个简易的配置中心,顺带整合到了SpringCloud】上面讲了在项目启动的时候SpringCloud是如何从配置中心加载数据的,主要是通过新建一个容器,加载bootstrap配置文件和一些配置类 , 最后会调用PropertySourceLocator来从配置中心获取到配置信息 。
那么在SpringCloud环境下,是如何实现注入到Bean中的属性动态刷新的呢?
举个例子

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
UserService
当在类上加一个@RefreshScope注解之后,那么当配置中心sanyou.username的属性有变化的时候,那么此时注入的username也会跟着变化 。
这种变化是如何实现的呢?
SpringCloud中规定 , 当配置中心客户端一旦感知到服务端的某个配置有变化的时候 , 需要发布一个RefreshEvent事件来告诉SpringCloud配置有变动 。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
在SpringCloud中RefreshEventListener类会去监听这个事件 , 一旦监听到这个事件,就会进行两步操作来刷新注入到对象的属性 。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
RefreshEventListener
  • 从配置中心再次拉取属性值 , 而这个拉取的代码逻辑跟项目启动时拉取的属性值核心逻辑几乎是一样的,也是创建一个新的spring容器,加载配置文件和配置类,最后通过PropertySourceLocator获取属性 , 这一部分核心的代码逻辑是复用的 。
  • 有了最新的属性之后,就开始刷新对象的属性 。
刷新的逻辑实现的非常的巧妙,可不是你以为的简单地将新的属性重新注入对象中,而是通过动态代理的方式来实现的 。
对于在类上加了@RefreshScope注解的Bean,Spring在生成这个Bean的时候,会进行动态代理 。
这里我们就上面举个UserService例子来分析,在生成UserService有两步操作
  • 生成一个UserService对象,将从配置中心拉到的配置sanyou.username注入给UserService对象
  • 由于加了@RefreshScope,会给上一步骤生成的UserService对象进行代理,生成一个代理对象
最后真正暴露出去供我们使用的其实是就是这个代理对象,如图所示

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
由于暴露出去的是一个代理对象,所以当调用getUsername方法的时候,其实是调用UserService的代理对象的getUsername方法,从而就会找到UserService,调用UserService的getUsername获取到username的属性值 。
当配置中心的配置有变动刷新属性的时候,Spring会把UserService这个对象(非代理对象)给销毁,重新创建一个UserService对象,注入最新的属性值 。
当再次通过UserService代理对象获取username属性的时候,就会找最新创建的那个UserService对象,此时就能获取到最新的属性值 。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
配置每刷新一次,UserService对象就会先销毁再重新创建,但是暴露出去的UserService代理对象一直不会变 。
这样,对于使用者来说,好像是UserService对象的属性自动刷新了,其实本质上是UserService代理对象最终找的UserService对象发生了变化 。
到这应该就知道为什么加了@RefreshScope的对象能够实现配置的自动刷新了,其实依靠的是动态代理完成的 。
3、源码执行流程图由于上面并没有涉及整体执行流程的源码分析 , 所以我特地结合源码画了两张源码的执行流程图,有兴趣的小伙伴可以对照着图翻一翻具体的源码 。
3.1启动时加载配置流程

推荐阅读