pom.xml
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.62version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.5version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
<version>1.7.5version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
<version>1.0.9version>
<exclusions>
<exclusion>
<artifactId>slf4j-apiartifactId>
<groupId>org.slf4jgroupId>
exclusion>
exclusions>
dependency>
dependencies>
design-19.0-0
|——src
|——main
|--java
|--com.lino.design
|-LotteryResult.java
|-MinibusTargetService.java
MinibusTargetService.java
package com.lino.design;
/**
* @description: 小客车指标调控服务
*/
public class MinibusTargetService {
/**
* 模拟摇号
*
* @param uId 用户编号
* @return 结果
*/
public String lottery(String uId) {
return Math.abs(uId.hashCode()) % 2 == 0 ?
"恭喜你,编码".concat(uId).concat("在本次摇号中签")
: "很遗憾,编码".concat(uId).concat("在本次摇号未中签或摇号资格已过期");
}
}
LotteryResult.java
package com.lino.design;
import java.util.Date;
/**
* @description: 摇号结果类
*/
public class LotteryResult {
/**
* 用户ID
*/
private String uId;
/**
* 摇号信息
*/
private String msg;
/**
* 业务时间
*/
private Date dateTime;
public LotteryResult(String uId, String msg, Date dateTime) {
this.uId = uId;
this.msg = msg;
this.dateTime = dateTime;
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Date getDateTime() {
return dateTime;
}
public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}
}
按照需求需要在原有的摇号接口中添加 MQ 消息发送以及短信息通知功能。
如果是最直接的方式那么可以直接在方法中补充功能即可。
<dependencies>
<dependency>
<groupId>com.linogroupId>
<artifactId>design-19.0-0artifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
design-19.0-1
|——src
|——main
|--java
|--com.lino.design
|-LotteryService.java
|-LotteryServiceImpl.java
|--test
|--com.lino.design.test
|-ApiTest.java
LotteryService.java
package com.lino.design;
/**
* @description: 摇号接口
*/
public interface LotteryService {
/**
* 摇号
*
* @param uId 用户编号
* @return 摇号结果
*/
LotteryResult doDraw(String uId);
}
LotteryServiceImpl.java
package com.lino.design;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
/**
* @description: 摇号接口实现类
*/
public class LotteryServiceImpl implements LotteryService {
private Logger logger = LoggerFactory.getLogger(LotteryServiceImpl.class);
private MinibusTargetService minibusTargetService = new MinibusTargetService();
@Override
public LotteryResult doDraw(String uId) {
// 摇号
String lottery = minibusTargetService.lottery(uId);
// 发短信
logger.info("给用户 {} 发送短信通知(短信):{}", uId, lottery);
// 发MQ信息
logger.info("记录用户 {} 摇号结果(MQ):{}", uId, lottery);
return new LotteryResult(uId, lottery, new Date());
}
}
ApiTest.java
package com.lino.design.test;
import com.alibaba.fastjson.JSON;
import com.lino.design.LotteryResult;
import com.lino.design.LotteryService;
import com.lino.design.LotteryServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: 单元测试
*/
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test() {
LotteryService lotteryService = new LotteryServiceImpl();
LotteryResult result = lotteryService.doDraw("2765789109876");
logger.info("测试结果:{}", JSON.toJSONString(result));
}
}
测试结果
17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 给用户 2765789109876 发送短信通知(短信):很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期
17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 记录用户 2765789109876 摇号结果(MQ):很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期
17:06:15.122 [main] INFO com.lino.design.test.ApiTest - 测试结果:{"dateTime":1675760774946,"msg":"很遗憾,编码2765789109876在本次摇号未中签或摇号资格已过期","uId":"2765789109876"}
<dependencies>
<dependency>
<groupId>com.linogroupId>
<artifactId>design-19.0-0artifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
design-19.0-2
|——src
|——main
|--java
|--com.lino.design
|--event
| |--listener
| | |--EventListener.java
| | |--MessageEventListener.java
| | |--MQEventListener.java
| |--EventManager.java
|-LotteryService.java
|-LotteryServiceImpl.java
|--test
|--com.lino.design.test
|-ApiTest.java
LotteryService
定义的是抽象类,因为这样可以通过抽象类将事件功能屏蔽,外部业务流程开发者不需要知道具体的通知操作。EventListener.java
package com.lino.design.event.listener;
import com.lino.design.LotteryResult;
/**
* @description: 事件监听接口
*/
public interface EventListener {
/**
* 监听事件
*
* @param result 摇号结果
*/
void doEvent(LotteryResult result);
}
T
。MessageEventListener.java
package com.lino.design.event.listener;
import com.lino.design.LotteryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: 短消息事件监听实现
*/
public class MessageEventListener implements EventListener {
private Logger logger = LoggerFactory.getLogger(MessageEventListener.class);
@Override
public void doEvent(LotteryResult result) {
logger.info("给用户 {} 发送短信通知(短信):{}", result.getuId(), result.getMsg());
}
}
MQEventListener.java
package com.lino.design.event.listener;
import com.lino.design.LotteryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: MQ事件监听实现
*/
public class MQEventListener implements EventListener {
private Logger logger = LoggerFactory.getLogger(MQEventListener.class);
@Override
public void doEvent(LotteryResult result) {
logger.info("记录用户 {} 摇号结果(MQ):{}", result.getuId(), result.getMsg());
}
}
EventManager.java
package com.lino.design.event;
import com.lino.design.LotteryResult;
import com.lino.design.event.listener.EventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @description: 事件处理器
*/
public class EventManager {
Map<Enum<EventType>, List<EventListener>> listeners = new HashMap<>();
public EventManager(Enum<EventType>... operations) {
for (Enum<EventType> operation : operations) {
this.listeners.put(operation, new ArrayList<>());
}
}
public enum EventType {
/**
* 事件类型
*/
MQ, Message
}
/**
* 订阅
*
* @param eventType 事件类型
* @param listener 监听
*/
public void subscribe(Enum<EventType> eventType, EventListener listener) {
List<EventListener> users = listeners.get(eventType);
users.add(listener);
}
/**
* 取消订阅
*
* @param eventType 事件类型
* @param listener 监听
*/
public void unsubscribe(Enum<EventType> eventType, EventListener listener) {
List<EventListener> users = listeners.get(eventType);
users.remove(listener);
}
/**
* 通知
*
* @param eventType 事件类型
* @param result 结果
*/
public void notify(Enum<EventType> eventType, LotteryResult result) {
List<EventListener> users = listeners.get(eventType);
for (EventListener listener : users) {
listener.doEvent(result);
}
}
}
subscribe
、取消订阅 unsubscribe
、通知 notify
。这三个方法分别用于对监听事件的添加和使用。EventType.MQ
、EventType.Message
LotteryService.java
package com.lino.design;
import com.lino.design.event.EventManager;
import com.lino.design.event.listener.MQEventListener;
import com.lino.design.event.listener.MessageEventListener;
/**
* @description: 摇号抽象类
*/
public abstract class LotteryService {
private EventManager eventManager;
public LotteryService() {
eventManager = new EventManager(EventManager.EventType.MQ, EventManager.EventType.Message);
eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener());
eventManager.subscribe(EventManager.EventType.Message, new MessageEventListener());
}
public LotteryResult draw(String uId) {
LotteryResult lotteryResult = doDraw(uId);
eventManager.notify(EventManager.EventType.MQ, lotteryResult);
eventManager.notify(EventManager.EventType.Message, lotteryResult);
return lotteryResult;
}
/**
* 执行摇号
*
* @param uId 用户编号
* @return 结果
*/
protected abstract LotteryResult doDraw(String uId);
}
abstract LotteryResult doDraw(String uId)
,让类的继承者实现。protected
,也就是保证将来外部的调用方不会调用到此方法,只有调用到 draw(String uId)
才能完成事件通知。eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener())
。eventManager.EventType.Message
,就执行哪些事件通知,按需添加。LotteryServiceImpl.java
package com.lino.design;
import java.util.Date;
/**
* @description: 摇号服务实现
* @author: lingjian
* @createDate: 2023/2/6 17:02
*/
public class LotteryServiceImpl extends LotteryService {
private MinibusTargetService minibusTargetService = new MinibusTargetService();
@Override
protected LotteryResult doDraw(String uId) {
// 摇号
String lottery = minibusTargetService.lottery(uId);
// 结果
return new LotteryResult(uId, lottery, new Date());
}
}
ApiTest.java
package com.lino.design.test;
import com.alibaba.fastjson.JSON;
import com.lino.design.LotteryResult;
import com.lino.design.LotteryService;
import com.lino.design.LotteryServiceImpl;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @description: 单元测试
*/
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test_draw() {
LotteryService lotteryService = new LotteryServiceImpl();
LotteryResult result = lotteryService.draw("1000000101010019");
logger.info("测试结果:{}", JSON.toJSONString(result));
}
}
测试结果
19:45:45.314 [main] INFO c.l.d.event.listener.MQEventListener - 记录用户 1000000101010019 摇号结果(MQ):恭喜你,编码1000000101010019在本次摇号中签
19:45:45.319 [main] INFO c.l.d.e.l.MessageEventListener - 给用户 1000000101010019 发送短信通知(短信):恭喜你,编码1000000101010019在本次摇号中签
19:45:45.398 [main] INFO com.lino.design.test.ApiTest - 测试结果:{"dateTime":1675770345311,"msg":"恭喜你,编码1000000101010019在本次摇号中签","uId":"1000000101010019"}