MQ消息处理方式(自定义注解)

mq回调的类,一般都提供onMessage, messageArrived这样的方法让我们重写,

但是我们的需求是通过不同topic,去调用不同的方法,

如果使用if else开发,那都会写到一个文件,

回调和消息处理函数耦合度也很高,也不利于团队的开发,

通过改造可以达到以下效果,业务代码写到单独的文件中,只要加上注解就可以。

此处采用反射调用的方法处理,使业务代码与回调分离,代码看起来更优雅

(如果有其它更优雅的方法记得跟我说哦!大家多交流学习)

最终效果 :

@Slf4j
@MqttEvent
public class MqttConsumer {

    @MyMqttTopic("mqtt.info")
    public void info(List<Object> params) throws IllegalAccessException {
         //处理业务代码
    }
}

回调函数中只需要写一句处理消息的代码

建立事件相关的类!

扫描二维码关注公众号,回复: 11436023 查看本文章
/**
 * @author louis
 */
public class Event {
    private String name;
    private IEventHandler handler;

    public Event() {

    }

    public Event(String name, IEventHandler handler) {
        this.name = name;
        this.handler = handler;
    }

    public String getName() {
        return name;
    }

    public void setHandler(IEventHandler handler) {
        this.handler = handler;
    }

    public IEventHandler getHandler() {
        return handler;
    }

    public void setName(String name) {
        this.name = name;
    }
}

事件触发类


/**
 * @author louis
 */
public class EventEmitter {
    private List<Event> eventList = new ArrayList<>();

    void on(String eventName, IEventHandler iEventHandler) {
        if (eventName == null || iEventHandler == null) {
            throw new IllegalArgumentException("event is invalid");
        }
        eventList.add(new Event(eventName, iEventHandler));
    }

    void emit(String eventName, List<Object> params) throws Exception {
        for (Event event : eventList) {
            if (event.getName().equals(eventName)) {
                event.getHandler().handle(params);
            }
        }
    }
}

事件注册类

/**
 * @author louis
 */
public class EventRegister {
    private EventRegister() {

    }
    private static EventEmitter emitter = new EventEmitter();
    public static void emit(String event, List<Object> params) throws Exception {
        emitter.emit(event, params);
    }
    @SuppressWarnings("ALL")
    public static void regist(String packageName, Class methodAnnotation, Class classAnnotation) throws Exception {
        URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(packageName.replace(".", "/"));

        if (scannedUrl == null) {
            throw new IllegalArgumentException();
        }

        File scannedFile = new File(scannedUrl.getFile());
        List<Class<?>> classes = ClassUtil.getClass(scannedFile, packageName);

        for (Class<?> cls : classes) {
            if (cls.isInterface()) {
                continue;
            }
            Annotation classAnnotationObj = cls.getAnnotation(classAnnotation);
            if (classAnnotationObj != null) {
                Object handler = cls.newInstance();
                Method[] methods = cls.getMethods();

                for (Method method : methods) {
                    Annotation methodAnnoationObj = method.getAnnotation(methodAnnotation);

                    if (methodAnnoationObj != null) {
                        Method valueMethod = methodAnnoationObj.annotationType().getDeclaredMethod("value");
                        String value = (String)valueMethod.invoke(methodAnnoationObj);

                        if (value != null && !"".equals(value)) {
                            emitter.on(value, params -> {
                                method.invoke(handler, params);
                            });
                        }
                    }
                }
            }
        }
    }
}

事件处理接口

/**
 * @author louis
 */
public interface IEventHandler {
    void handle(List<?> params) throws Exception;
}

创建类注解

/**
 * @author louis
 */
@Target(value = ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MqttEvent {
}

创建方法注解


/**
 * @author louis
 */
@Target(value = ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyMqttTopic {
    String value();
}

建立一个MessageHandle类,注册事件调用,并触发消息

@Slf4j
public class MessageHandler {
    static {
        try {
            EventRegister.regist(MessageHandler.class.getPackage().getName(), MyMqttTopic.class, MqttEvent.class);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
    }

    public static void handleMqttMessage(String topic, String message) throws Exception {
        
        MqttMessage message1 = JSON.parseObject(message, MqttMessage.class);

        if (isNotValidMessage(message1)) {
            return;
        }

        EventRegister.emit("mqtt." + message1.getCmd(), new ArrayList<Object>() {{
            add(message1);
          }});
        }
   
}

然后就可以编写业务代码

猜你喜欢

转载自blog.csdn.net/dhLianga/article/details/107556065