Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package koper.event; import com.alibaba.fastjson.JSON; import koper.DefaultMessageDispatcher; import koper.Listen; import koper.MsgBean; import koper.MsgBeanListener; import koper.convert.ConverterCenter; import koper.util.ReflectUtil; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.List; import java.util.Optional; /** * ??? * * @author caie * @since 1.2 */ public class DataEventMessageDispatcher extends DefaultMessageDispatcher { private static Logger log = LoggerFactory.getLogger(DataEventMessageDispatcher.class); @Override protected void triggerMessageListener(MsgBean<String, String> msgBean, Object listener) { try { // onMessageBeanmsgBean if (listener.getClass().getAnnotation(Listen.class) != null || listener instanceof MsgBeanListener) { super.triggerMessageListener(msgBean, listener); } else { triggerDataEventMethod(listener, msgBean); } } catch (Throwable e) { log.error(e.getMessage(), e); } } /** * @param listener */ private void triggerDataEventMethod(Object listener, MsgBean<String, String> msgBean) { Class<?> clazz = listener.getClass(); DataListener dataListener = clazz.getAnnotation(DataListener.class); String dataObject = dataListener.dataObject(); triggerDataEvent(listener, dataObject, msgBean); } private void triggerDataEvent(Object listener, String dataObject, MsgBean<String, String> msgBean) { if (log.isDebugEnabled()) log.debug("AbstractDataEventListener??: " + msgBean); Class<?> clazz = listener.getClass(); DataEvent dataEvent = JSON.parseObject(msgBean.getValue(), DefaultDataEvent.class); // args : [{"xxx" : xxx, "xxx" : xxx}] dataEvent.setTopic(msgBean.getTopic()); dataEvent.setDataObjectName(dataObject); String event = msgBean.getTopic(); String eventName = getEventName(event); dataEvent.setEventName(eventName); dataEvent.setMsgBean(msgBean); try { if (log.isDebugEnabled()) log.debug("DataEvent?:{}", event); final Optional<Method> methodOptional = ReflectUtil.getMethod(clazz, eventName, method -> method.getParameters().length == dataEvent.getArgs().size() || method.getParameters().length == dataEvent.getArgs().size() + 1 || method.getParameters().length == 1); if (methodOptional.isPresent()) { final Method method = methodOptional.get(); Object[] methodParameters = getDataEventMethodParameters(method, dataEvent); ReflectUtil.invoke(listener, method, methodParameters); } else { log.warn( "Message received! But no event handle method defined {}(DataEvent dataEvent) Message is {}", event, msgBean.getValue()); } } catch (Exception e) { log.warn("Fail to call event handle method {}(DataEvent dataEvent). Message is {}. Exception:{}", event, msgBean.getValue(), e); throw new RuntimeException(e); } } /** * ? (?) * * @param method * @param dataEvent ? * @return ?(Object[]) * @throws InstantiationException * @throws IllegalAccessException */ private Object[] getDataEventMethodParameters(Method method, DataEvent dataEvent) throws InstantiationException, IllegalAccessException { final List<?> args = dataEvent.getArgs(); final int length = method.getParameters().length; Object[] parameters = new Object[length]; for (int i = 0; i < length; i++) { final Parameter parameter = method.getParameters()[i]; final Class<?> parameterTypeClass = parameter.getType(); Object o1; // ?args?, ?? DataEvent if (i == args.size()) { o1 = dataEvent; } else { Object o = args.get(i); if (parameterTypeClass.getName().equals(DataEvent.class.getName())) { o1 = dataEvent; } else { o1 = ConverterCenter.convertValue(parameterTypeClass, o); } } parameters[i] = o1; } return parameters; } /** * ?Topic???, onXXX. * : * koper.demo.trading.mapper.impl.OrderMapperImpl.insertOrder * ???? onInsertOrder * * @param event topic * @return ?? */ private String getEventName(String event) { event = StringUtils.substring(event, event.lastIndexOf('.') + 1); event = StringUtils.substring(event, 0, 1).toUpperCase() + StringUtils.substring(event, 1); event = "on" + event; return event; } }