在实际项目中,我们往往需要自定义一些事件和监听器来满足业务场景,比如在微服务中会有这样的场景:
服务 A 在处理完某个逻辑之后,需要通知微服务 B 去处理另一个逻辑,或者微服务 A 处理完某个逻辑之后,需要将数据同步到微服务 B,这种场景非常普遍,这个时候,我们可以自定义事件以及监听器来监听,一旦监听到微服务 A 中的某事件发生,就去通知微服务 B 处理对应的逻辑。
步骤1, 自定义事件A
public class MyEvent extends ApplicationEvent { private User user; public MyEvent(Object source, User user) { super(source); //这里写服务A的内容,如下 this.user = user; ystem.out.println("A服务完成"); } public User getUser() { return user; } }
步骤2, 监听事件A,在监听事件中 实现B或者B
@Component public class MyEventListener implements ApplicationListener<MyEvent> { public void onApplicationEvent(MyEvent myEvent) { User user = myEvent.getUser(); // 一旦MyEvent事件发生,这里就会执行 // 处理事件,实际项目中可以通知别的微服务或者处理其他逻辑等等 System.out.println("用户名:" + user.getUsername()); System.out.println("密码:" + user.getUserpwd()); System.out.println("监听事件发生后, 通知的服务已经完成"); } }
步骤3,发布事件
@Service public class UserService { @Resource private ApplicationContext applicationContext; /** * 发布事件 * @return */ public User getUser2() { User user = new User(1L, "庄子", "123456"); //发布事件 MyEvent event = new MyEvent(this, user); applicationContext.publishEvent(event); return user; } }
在 service 中注入 ApplicationContext,在业务代码处理完之后,通过 ApplicationContext 对象手动发布 MyEvent 事件,这样我们自定义的监听器就能监听到,然后处理监听器中写好的业务逻辑。
最后,在 Controller 中写一个接口来测试一下
@Resource private UserService userService; @GetMapping("/publish") public String eventPublish() { userService.getUser2(); return "success"; }
执行流程:调用服务,发布事件,事件发布后,会被监听到
浏览器访问 http://localhost:8001/listener/publish