背景:项目上正在使用的消息处理服务框架,对于多种消息来源和多种消息类型分类处理,整理一个简化版本。
核心是注解类MessageHandlerType,标明消息的来源和操作类型。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Service
public @interface MessageHandlerType {
String operateType();
String source();
}
定义不同类型的消息体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MessageBody1 implements Serializable {
private String source;
private String operation;
private String status;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MessageBody2 implements Serializable {
private String source;
private String operation;
private String orderId;
}
注解实现类MessageHandlerTypeImpl
public class MessageHandlerTypeImpl implements MessageHandlerType {
private String operateType;
private String source;
public MessageHandlerTypeImpl(String operateType, String source) {
this.operateType = operateType;
this.source = source;
}
@Override
public String operateType() {
return operateType;
}
@Override
public String source() {
return source;
}
@Override
public Class<? extends Annotation> annotationType() {
return MessageHandlerType.class;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MessageHandlerType)){
return false;
}
MessageHandlerType other = (MessageHandlerType)o;
return source.equals(other.source())&&operateType.equals(other.operateType());
}
@Override
public int hashCode() {
int hashCode =0;
hashCode+=(127 * "source".hashCode()) ^ source.hashCode();
hashCode+=(127 * "operateType".hashCode()) ^ operateType.hashCode();
return hashCode;
}
}
消息处理接口MessageHandler
public interface MessageHandler<T> {
void handler(T data) ;
}
消息实现类(具体实现功能),上面加上@MessageHandlerType注解标明消息来源和具体操作
@Component
@MessageHandlerType(operateType = Constants.Type.OPERATE_TYPE1,source = Constants.SOURCE_FROM_SOURCE1)
public class MessageHandlerImpl1 implements MessageHandler<MessageBody1> {
@Override
public void handler(MessageBody1 data) {
System.out.println(JSON.toJSONString(data));
}
}
@Component
@MessageHandlerType(operateType = Constants.Type.OPERATE_TYPE2,source = Constants.SOURCE_FROM_SOURCE2)
public class MessageHandlerImpl2 implements MessageHandler<MessageBody2> {
@Override
public void handler(MessageBody2 data) {
System.out.println(JSON.toJSONString(data));
}
}
消息服务(最核心)将所有带@MessageHandlerType注解上参数信息和注解类一一对应存入map集合
@Service
public class MessageService<T> {
/**
* 自理解:messageHandlerMap的key是满足operateType固定等于xx和source固定等于yy的一个实现类
*/
private Map<MessageHandlerType, MessageHandler> messageHandlerMap;
/**
* Spring会先实例化所有Bean,然后根据配置进行扫描,当检测到@Autowired后进行注入,注入时调用这个方法
*/
@Autowired
public void setMessageHandlerMap(List<MessageHandler> messageHandlers) {
//注入各种类型的消息处理类
messageHandlerMap = messageHandlers.stream().collect(Collectors.toMap(
messageHandler -> AnnotationUtils.findAnnotation(messageHandler.getClass(), MessageHandlerType.class),
v -> v, (v1, v2) -> v2));
}
public void doHandler(String action, String source, T t) {
MessageHandlerTypeImpl messageHandlerType = new MessageHandlerTypeImpl(action, source);
MessageHandler messageHandler = messageHandlerMap.get(messageHandlerType);
if (null != messageHandler) {
messageHandler.handler(t);
}
}
}
常量类
public class Constants {
/**
* 消息操作类型
*/
public interface Type {
String OPERATE_TYPE1 = "operateType1";
String OPERATE_TYPE2 = "operateType2";
}
public final static String SOURCE_FROM_SOURCE1= "source1";
public final static String SOURCE_FROM_SOURCE2 = "source2";
}
测试类
@RestController
public class MessageServiceTest {
@Autowired
private MessageService messageService;
@RequestMapping(value = "/test")
public String index() {
messageService.doHandler(Constants.Type.OPERATE_TYPE1, Constants.SOURCE_FROM_SOURCE1,
new MessageBody1(Constants.Type.OPERATE_TYPE1, Constants.SOURCE_FROM_SOURCE1, "accept"));
messageService.doHandler(Constants.Type.OPERATE_TYPE2, Constants.SOURCE_FROM_SOURCE2,
new MessageBody2(Constants.Type.OPERATE_TYPE2, Constants.SOURCE_FROM_SOURCE2, "111111"));
return "success";
}
}
测试结果:
实际应用中可以接收各种交互方消息,具体对应的操作逻辑用一个具体的Handler实现类处理即可。