概述:最近一直在搞Java-DDD模式开发的方案落地;
个人的理解,DDD模式中,只要关注三个模块即可:
A. application:应用层,可以是http接口服务,也可以是grpc服务接口,甚至是rpc服务;
B. domain:领域层,主要是领域业务的具体实现,跟上层的应用没有任何关系;
C. infrastructure:基础服务层,包括项目中的持久化之类的代码;
那么,如何将这三层进行较好的解耦,各式其责,在这里想到了java的事件机制!
看了一些解决方案,没有达到自己的预期,
0.1 要么太重了,比如MQ服务;
0.2 要么,还是侵入式太强,比如spring的事件机制;
0.3 java原生的事件机制,支持的也不好,自己封装,又太费时;
最终,选定 JFinal-event 作为事件机制进行使用,简单,轻量,又解决了紧耦合问题!
具体细节:JFinal-event: JFinal-event事件驱动插件,无任何第三方依赖,小巧玲珑。
下面开始应用(基于spring boot):
1. 添加maven依赖:
net.dreamlu
JFinal-event
3.1.2
com.jfinal
jfinal
5.0.0
注意:下方的jfinal依赖要加上,不然会报 jfinal.log找不到的问题,这一点不是太好!
2. 配置 EventPlugin,在项目合适的位置:
import net.dreamlu.event.EventPlugin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 事件插件配置
* YangKuo 2022/5/24 14:39
*/
@Configuration
public class EventConfig {
@Bean
public EventPlugin createEventPlugin() {
EventPlugin plugin = new EventPlugin();
// 设置为异步,默认同步,或者使用`threadPool(ExecutorService executorService)`自定义线程池。
plugin.async();
// 开启类扫描,默认为 false,用于不支持注解处理器的情况,用于不使用 maven 或者不支持注解处理器的情况。
plugin.enableClassScan();
// 扫描 jar 里的 监听器,默认不扫描,在开启 enableClassScan 有效果
plugin.scanJar();
// 扫描的包,默认全扫描,可提升启动速度,在开启 enableClassScan 有效果,多个路径,用;
plugin.scanPackage("com.*.event;com.*.*.event");
//手动启动插件,用于main方法启动,jfinal中不需要,添加插件即可。
plugin.start();
return plugin;
}
}
3. 创建事件类,继承 ApplicationEvent
/**
* 广告保存事件
* YangKuo 2022/5/24 11:39
*/
public class AdSaveEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
public AdSaveEvent(String source) {
super(source);
}
}
4. 触发事件:我这里测试在领域层触发保存业务:
public void testEvent(){
EventKit.post(new AdSaveEvent("Hello"));
}
5. 添加事件监听:核心注解:@EventListener,这个业务下面还可以加入多个listener
/**
* 广告业务监听类
* YangKuo 2022/5/24 11:51
*/
public class AdEventListener {
@EventListener
public void adSave(AdSaveEvent adSaveEvent) {
String source = adSaveEvent.getSource();
//保存广告业务
System.out.println("我监听到 " + source + " 要保存广告了!");
}
}
测试最美结果:
这样子,我们就能将各个层级进行解耦,每个模块子负责关心自己的业务逻辑即可,互不侵扰!
你的努力,终将成为你最有力的资本!