之前一个项目,有两个模块,A 模块需要依赖 B 模块,但现在 B 模块有地方需要调用 A 模块的方法,如果直接依赖,又会产生循环依赖问题。最终选择使用 spring 的事件监听来解决该问题。
思路就是,B 模块去发布事件,A 中监听,得到数据后,通过引用返回给 B。
首先是定义事件
public class getUserInfoEvent extends ApplicationEvent {private String message;private Integer griddingId;private StringBuilder griddingName;public getUserInfoEvent(Object source, String message, Integer griddingId, StringBuilder griddingName) {super(source);this.message = message;this.griddingId = griddingId;this.griddingName = griddingName;//接收要获取到值的StringBuilder}public StringBuilder getGriddingName() {return griddingName;}public Integer getGriddingId() {return griddingId;}public String getMessage() {return message;}
}
然后在 B 中去发布事件
@AutowiredApplicationEventPublisher applicationEventPublisher; //这个必须注入@Overridepublic SysUserVO getUserInfo(Long userId) {SysUser user = getById(userId);Integer griddingId = user.getGriddingId();StringBuilder griddingName= new StringBuilder(); //使用stringbuilder进行引用字符串操作,来获取需要的值//上面是业务相关getUserInfoEvent event = new getUserInfoEvent(this,"发布“获取用户信息”事件",griddingId,griddingName); //定义事件applicationEventPublisher.publishEvent(event); //发布事件//下面是获取到数据之后的操作,不重要//这里事件是同步进行的SysUserVO sysUserVO = new SysUserVO();BeanUtils.copyProperties(user,sysUserVO);sysUserVO.setGriddingName(griddingName.toString());// 找到该用户所属角色String roleName = getRoleByUserId(userId);sysUserVO.setRoleName(roleName);SysUser parentUser = sysUserMapper.selectById(user.getParentId());sysUserVO.setParentName(ObjectUtils.isEmpty(parentUser) ? null : parentUser.getUserName());return sysUserVO;}
最后在 A 中监听事件
@EventListener
public void getGriddingNameByUserIdEventListener(getUserInfoEvent event) { //参数必须填写要监听的事件类,事件发布后这边就会监听到//形参event中存有传递的相关数据System.out.println(event.getMessage()); //会打印出---发布“获取用户信息”事件//下面为个人业务相关代码Integer griddingId = event.getGriddingId();StringBuilder griddingName = event.getGriddingName();//再通过网格id来查找对应的网格信息GriddingArea griddingArea = getOne(new LambdaQueryWrapper<GriddingArea>().eq(GriddingArea::getId, griddingId));griddingName.append(griddingArea.getGriddingName()); //使用同一个StringBuilder对象来操作,这里把获取到的字符串存入后,事件发布者那边就能得到数据了。System.out.println("griddingName"+griddingName);
}
非常好用👍