"对于Spring框架,现实公司使用的非常广泛,但是由于业务的复杂程度不同,了解到很多小伙伴们利用Spring开发仅仅是利用了Spring的IOC,即使是AOP也很少用,但是目前的Spring是一个大家族,形成了一个很大的生态,覆盖了我们平时开发的方方面面,抛开特殊的苛刻要求之外,Spring的生态其实已经很全面了,所以在此开个系列来研究下Spring提供给我们的一些平时不太却又很实用的内容。"
说明:
我们平时在开发的时候都在讲高内聚低耦合,而且目前开发业务的时候业务一般在一个工程内部,但是为了考虑后期的可维护性,所以内部又以包名划分出了多个业务模块,但是有时不可避免的出现多个模块之间业务调用的情况。尤其是在采用RPC框架的时候,我们可能抽象出了一些服务接口,但是在同一个工程内部,RPC服务接口互相调用总觉得怪怪的,有没有相对优雅的方式来处理呢?答案是有的,就是利用Spring的事件监听模式。
定义一个场景:用户签到并获取积分,用户签到,记录签到信息,然后给用户添加对应的签到积分。
根据描述我们需要划分一下模块:积分模块,签到模块。下面开始设计代码
1、积分模块
1.1、积分业务接口
public interface PointBizService {
/**
* 处理用户积分
*
* @param source
* @return
*/
public long handleUserPoint(int source);
1.2、积分业务实现类
@Service
public class PointBizServiceImpl implements PointBizService {
@Override
public long handleUserPoint(int source) {
return 0;
}
}
1.3、积分事件
public class PointEvent<PointHandleVO> extends ApplicationEvent {
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public PointEvent(PointHandleVO source) {
super(source);
}
1.4、积分事件处理监听器
@Component
public class PointEventListener implements ApplicationListener {
@Autowired
private PointBizService pointBizService;
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof PointEvent) {
System.out.println("处理积分业务事件");
PointHandleVO pointHandleVO = (PointHandleVO) event.getSource();
pointBizService.handleUserPoint(pointHandleVO.getSource());
}
}
}
2、签到模块
2.1、签到业务接口
public interface SignBizService {
/**
* @param uid
* @return
*/
public boolean userSign(long uid);
}
2.2、签到业务实现类
@Service
public class SignBizServiceImpl implements SignBizService {
@Autowired
private ApplicationContextUtils applicationContextUtils;
@Override
public boolean userSign(long uid) {
//....处理原有的业务
applicationContextUtils.getApplicationContext().publishEvent(new PointEvent(new PointHandleVO(2)));
return false;
}
}
3、工具类
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
}
以上是整体业务的核心代码,简单梳理下监听器的流程:1、用户处理完原有的签到业务后,通过工具类获取到ApplicationContext类,然后调用publishEvent(ApplicationEvent event)方法发布事件,然后PointEventListener事件监听器类监听到自己的PointEvent事件,进行业务处理,这样的实现避免了业务服务的直接调用,看着简洁些,但是这个也有个缺点:这种写法只能在同一个java进程中使用。如果是在分布式环境下利用好集群的特性,可以引入消息队列等第三方中间件来帮助实现业务的解耦。
虽说是比较简单的东西,但还是希望此篇文章对大家有所帮助。