盘点Spring/Boot的那些常用扩展点( 七 )


源码验证事件传播源码
从这段源码可以看出 , 如果父容器不为空 , 就会通过父容器再发布一次事件 。
传播特性的一个坑
前面说过 , 在容器启动的过程 , 会发布很多事件 , 如果你需要有相应的扩展 , 可以监听这些事件 。但是 , 在环境下 , 你的这些发布的事件的监听器可能会执行很多次 。为什么会执行很多次呢?其实就是跟传播特性有关 。
在的环境下 , 为了使像和这些不同的服务的配置相互隔离 , 会创建很多的子容器 , 而这些子容器都有一个公共的父容器 , 那就是项目启动时创建的容器 , 事件的监听器都在这个容器中 。而这些为了配置隔离创建的子容器 , 在容器启动的过程中 , 也会发布诸如t等这样的事件 , 如果你监听了这些事件 , 那么由于传播特性的关系 , 你的这个事件的监听器就会触发多次 。
如何解决这个坑呢?
你可以进行判断这些监听器有没有执行过 , 比如加一个判断的标志;或者是监听类似的事件 , 比如ent事件 , 这种事件是在启动中发布的事件 , 而子容器不是 , 所以不会多次发这种事件 , 也就会只执行一次 。
事件的运用举例
1、在中的使用
又来以举例了 。。的n监听了 , 然后判断如果是t就进行相应的处理 , 这个类还实现了接口 。。
class n
, ,{
@Overridepublic void onApplicationEvent(ApplicationEvent event) {if (failFast && event instanceof ContextRefreshedEvent) {// fail-fast -> check all statements are completedthis.sqlSessionFactory.getConfiguration().getMappedStatementNames();}}
}
说实话 , 这监听代码写的不太好 , 监听了 , 那么所有的事件都会回调这个类的方法 , 但是方法实现又是当是t类型才会往下走 , 那为什么不直接监听t呢?
可以给个差评 。
膨胀了膨胀了 。。
2、在的运用
在的中 , 当项目启动的时候 , 会自动往注册中心进行注册 , 那么是如何实现的呢?当然也是基于事件来的 。当web服务器启动完成之后 , 就发布事件 。
然后不同的注册中心的实现都只需要监听这个事件 , 就知道web服务器已经创建好了 , 那么就可以往注册中心注册服务实例了 。如果你的服务没往注册中心 , 看看是不是web环境 , 因为只有web环境才会发这个事件 。
提供了一个抽象类  , 实现了对Event(的父类)事件的监听
一般不同的注册中心都会去继承这个类 , 监听项目启动 , 实现往注册中心服务端进行注册 。
Nacos对于的继承
Event事件在内部中运用很多 , 是解耦合的利器 。在实际项目中 , 你既可以监听/Boot内置的一些事件 , 进行相应的扩展 , 也可以基于这套模型在业务中自定义事件和相应的监听器 , 减少业务代码的耦合 。
命名空间
最后来讲一个可能没有留意 , 但是很神奇的扩展点–命名空间 。起初我知道这个扩展点的时候 , 我都惊呆了 , 这玩意也能扩展?真的不得不佩服设计的可扩展性 。
回忆一下啥是命名空间?
先看一段配置

这一段xml配置想必都很熟悉 , 其中 , 标签就代表了一个命名空间 。