文章目录
前言:ApplicationListener 是spring提供的一个监听器,它可以实现一个简单的发布-订阅功能,用有点外行但最简单通俗的话来解释:监听到主业务在执行到了某个节点之后,在监听器里面做出相应的其它业务变更。下面我们具体看段代码,则能很快的理解:
再次推荐博主原创idea插件: Equals Inspection , 如果经常使用Objects.equals方法,相信这个插件可以有所帮助
(欢迎各位前往idea插件marketplace免费下载)
使用示例:
java代码:
首先定义一个业务实体类,实体类定义字段、get set方法、构造函数
importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructor/**
* 模拟业务对象实体类
* @author csdn:孟秋与你
*/publicclassMyBizEntity{privateString name;privateInteger age;}
再定义一个事件,事件继承ApplicationEvent
importorg.springframework.context.ApplicationEvent;/**
* 自定义事件(继承ApplicationEvent)
* @author csdn:孟秋与你
*/publicclassMyEventextendsApplicationEvent{publicMyEvent(Object source){super(source);}publicMyEvent(){// java基础:如果父类只有有参构造 子类需要使用其它构造函数 必须在构造函数第一行调用super 因为子类也是调用父类的构造函数super(null);// do other}}
定义一个监听器,实现ApplicationListener接口:
importorg.springframework.context.ApplicationEvent;importorg.springframework.context.ApplicationListener;importorg.springframework.stereotype.Component;/**
* 监听事件
*/@ComponentpublicclassMyApplicationListenerimplementsApplicationListener{@OverridepublicvoidonApplicationEvent(ApplicationEvent applicationEvent){// 必须判断自己要的类型 因为会监听到所有继承ApplicationEvent的事件if(applicationEvent instanceofMyEvent){Object source = applicationEvent.getSource();MyBizEntity bizEntity =(MyBizEntity) source;System.out.println(bizEntity.getName()+":------------name");}}}
写一个接口进行测试, 此时监听器就能打印输出了
importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.ApplicationContext;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;@RequestMapping("/test/listener")@RestControllerpublicclassMainBizController{@AutowiredprivateApplicationContext context;@GetMappingpublicStringtest(){// do something// 模拟要传递的业务对象MyBizEntity bizEntity =newMyBizEntity("name",18);MyEvent event =newMyEvent(bizEntity);// 上下文 发布事件
context.publishEvent(event);return"success";}}
原理简析:
为什么发布了事件,监听器就能够监听到呢? 其实原理很简单,就是spring进行了一个朴实无华的直接调用, 我们来看看源码:
context.publishEvent默认是调用AbstractApplicationContext类的publishEvent方法,而publishEvent方法里面调用了SimpleApplicationEventMulticaster 类的multicastEvent方法。
tips: 为什么上下文有publishEvent方法 ?
因为ApplicationContext继承了ApplicationEventPublisher
SimpleApplicationEventMulticaster: 首先会获取所有实现了ApplicationListener的监听器 (get by type就可以获取到), 接着会执行 invokeListener方法
我们看看最后doInvokeListener 做了什么:
通过上面源码链路,我们不难发现 其实就是调用了publishEvent方法后,spring在我们不轻易能看到的地方 去调用了一下监听器的onApplicationEvent 方法而已,通过源码我们也可以看到 默认是同步调用(没有定义taskExecutor时), 本质上是一个解耦,把原本可能要写在一起的业务代码拆分了。
版权归原作者 孟秋与你 所有, 如有侵权,请联系我们删除。