1、ApplicationContext事件机制是观察者设计模式的具体实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。
2、如果容器中由一个ApplicationListener Bean,当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean会自动触发,这种事件机制需要程序显示的触发,
3、其中Spring有一些内置的事件,当完成某种操作会发出某些事件动作,例如监听ContextRefreshedEvent事件,当所有Bean促使和完成并被成功装载会触发该事件,实现ApplicationListener<‘ContextRefreshedEvent’>接口可以收到监听动作,接着实现自己的业务逻辑,事件Event也可以自己自定义、监听Listener也可以自定义,根据业务逻辑按需处理。
文章目录
Spring观察者模式一、对象说明二、事件模式实体概念三、本文场景:容器启动的时候装填缓存数据(加载数据字典)
1.创建监听器CountryDirectoryEventListener2.运行截图 思考问题:事件的发布与监听是一个同步的过程是同步的?
1.创建自定义事件类:MessageEvent2.创建自定义事件监听类:MessageEventListener3.运行效果4.异步执行效果 高级写法@EventListener注解总结
一、对象说明
1、ApplicationContext容器对象
2、ApplicationEvent事件对象
3、ContextRefreshedEvent容器刷新事件
4、ApplicationListener事件监听对象
1.事件源:事件的触发的地方,比如我在容器加载的时候需要触发加载数据字典实现缓存预热。
2.事件:描述发生了什么事情的对象,比如上面的:加载数据字典数据
3.事件监听器:监听到事件发生的时候,做一些处理,比如更新缓存实现缓存预热
三、本文场景:容器启动的时候装填缓存数据(加载数据字典)
某个零售电商系统,mysql数据库中有储存系统内设置好的所有省市区信息,现在要将这部分地址数据查询出来放到redis做缓存(缓存预热),方便用户购买的时候自动级联填写快递省市区地址,为了避免直接写到监听的时候对象还未加载完毕,导致缓存预热失败,打算从ContextRefreshedEvent等容器加载完毕的时候进行缓存预热,可以进行以下处理:
1.创建监听器CountryDirectoryEventListenerCountryDirectoryEventListener必须实现ApplicationListener类并指定监听事件ContextRefreshedEvent,如果不指明监听类型则会监听所有事件,因为所有事件继承ApplicationContextEvent类
代码如下(示例):
@Componentpublic class CountryDirectoryEventListener implements ApplicationListener
这里只是打印输出,具体实现思路大致如此
MyApplicationEventListener类没有指定具体的监听器,则所有事件都会监听到
是的,事件的发布与监听是一个同步的过程,一般缓存预热这里可以使用异步的方法实现,通过在监听方法前使用@Async,并且工程要支持异步,springboot工程启动类需要加@EnableAsync注解。下面看看实际效果
1.创建自定义事件类:MessageEvent必须继承ApplicationEvent,可以支持多参数传递
@Componentpublic class MessageEventListener implements ApplicationListener
@Componentpublic class MessageEventListener implements ApplicationListener
这里偷懒不写接口调用方法,直接在刚刚缓存预热的监听方法之前去发布事件MessageEvent看看会不会是同步的。
@Componentpublic class CountryDirectoryEventListener implements ApplicationListener
事件的发布与监听是一个同步的过程
使用@Async注解
@Componentpublic class MessageEventListener implements ApplicationListener
@Componentpublic class CommentSyncEventListener { @Async @EventListener public void sync(CommentSyncEvent event) { logger.error("评论同步失败", e); } }
总结
Spring的事件机制简便地将我们的代码解耦从而优化我们的代码,方便我们扩展。