// Path: koper-core/src/main/java/koper/client/ConsumerLauncher.java
// public interface ConsumerLauncher {
// 
//     /**
//      * start consumer
//      */
//     public void start();
// 
//     void setAutoStart(boolean autoStart);
// 
//     void setPartitions(int partitions);
// 
//     /**
//      * @param threads
//      */
//     void setDispatcherThreads(int threads);
// 
//     /**
//      * @return
//      */
//     public ListenerRegistry getListenerRegistry();
// }
// 
// Path: koper-core/src/main/java/koper/util/ReflectUtil.java
// public class ReflectUtil {
// 
//     public void add(int abc, int xyz, String yyy) {
// 
//     }
// 
//     private static Map<String, Class<?>> classMap = new HashMap<>();
// 
//     /**
//      * 获取类上的Listen注解
//      *
//      * @param clazz Class类
//      * @return Listen注解
//      */
//     public static Listen getListenAnnotation(Class<?> clazz) {
//         return clazz.getAnnotation(Listen.class);
//     }
// 
//     /**
//      * Get method arg names.
//      *
//      * @param clazz
//      * @param methodName
//      * @return
//      */
//     public static <T> String[] getMethodArgNames(Class<T> clazz, String methodName) {
//         try {
//             ClassPool pool = ClassPool.getDefault();
//             CtClass cc = pool.get(clazz.getName());
// 
//             CtMethod cm = cc.getDeclaredMethod(methodName);
// 
//             // 使用javaassist的反射方法获取方法的参数名
//             MethodInfo methodInfo = cm.getMethodInfo();
//             CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
//             LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
//             if (attr == null) {
//                 throw new RuntimeException("LocalVariableAttribute of method is null! Class " + clazz.getName() + ",method name is " + methodName);
//             }
//             String[] paramNames = new String[cm.getParameterTypes().length];
//             int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
//             for (int i = 0; i < paramNames.length; i++)
//                 paramNames[i] = attr.variableName(i + pos);
// 
//             return paramNames;
//         } catch (NotFoundException e) {
//             throw new RuntimeException(e.getMessage(), e);
//         }
//     }
// 
//     public static Class<?> getClass(String className) {
//         return classMap.computeIfAbsent(className, clazzName -> {
//             try {
//                 return Class.forName(clazzName);
//             } catch (ClassNotFoundException e) {
//                 throw new RuntimeException(e);
//             }
//         });
//     }
// 
//     public static void invoke(Object targetObject, Method method, Object[] objects) {
//         final Class<?> clazz = targetObject.getClass();
//         final FastClass fastClass = FastClass.create(clazz);
//         try {
//             fastClass.getMethod(method).invoke(targetObject, objects);
//         } catch (InvocationTargetException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static Optional<Method> getMethod(Class<?> clazz, String eventName, Predicate<Method> methodPredicate) {
//         final Method[] methods = clazz.getDeclaredMethods();
// 
//         return Arrays.stream(methods)
//                 .filter(method -> method.getName().equals(eventName))
//                 .filter(methodPredicate)
//                 .findAny();
//     }
// 
//     public static void main(String[] args) throws NotFoundException {
// 
//         String[] paramNames = ReflectUtil.getMethodArgNames(ReflectUtil.class, "add");
//         // paramNames即参数名
//         for (int i = 0; i < paramNames.length; i++) {
//             System.out.println(paramNames[i]);
//         }
//     }
// 
// }


import koper.client.ConsumerLauncher;
import koper.util.ReflectUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
            // pojo listener
            final Listen listenAnnotation = bean.getClass().getAnnotation(Listen.class);
            final String topic = listenAnnotation.topic();
            if (StringUtils.isBlank(topic)) {
                throw new RuntimeException(
                        String.format("class %s, @Listen annotation topic not specified, please check", bean)
                );
            } else {
                registerListener(bean, topic);
            }
        }
        return bean;
    }

    /**
     * 注册消息监听器
     *
     * @param listener
     */
    protected void registerMsgBeanListener(MsgBeanListener listener) {

        Class<?> clazz = listener.getClass();
        Method method;
        String topic = null;
        Listen listen;
        method = getMethod(clazz, "onMsgBean");
        listen = method == null ? null : method.getAnnotation(Listen.class);

        if (listen == null) {
            // 先拿类上的 Listen 注解, 没有再拿方法上的Listen
// Path: koper-core/src/main/java/koper/client/ConsumerLauncher.java
// public interface ConsumerLauncher {
// 
//     /**
//      * start consumer
//      */
//     public void start();
// 
//     void setAutoStart(boolean autoStart);
// 
//     void setPartitions(int partitions);
// 
//     /**
//      * @param threads
//      */
//     void setDispatcherThreads(int threads);
// 
//     /**
//      * @return
//      */
//     public ListenerRegistry getListenerRegistry();
// }
// 
// Path: koper-core/src/main/java/koper/util/ReflectUtil.java
// public class ReflectUtil {
// 
//     public void add(int abc, int xyz, String yyy) {
// 
//     }
// 
//     private static Map<String, Class<?>> classMap = new HashMap<>();
// 
//     /**
//      * 获取类上的Listen注解
//      *
//      * @param clazz Class类
//      * @return Listen注解
//      */
//     public static Listen getListenAnnotation(Class<?> clazz) {
//         return clazz.getAnnotation(Listen.class);
//     }
// 
//     /**
//      * Get method arg names.
//      *
//      * @param clazz
//      * @param methodName
//      * @return
//      */
//     public static <T> String[] getMethodArgNames(Class<T> clazz, String methodName) {
//         try {
//             ClassPool pool = ClassPool.getDefault();
//             CtClass cc = pool.get(clazz.getName());
// 
//             CtMethod cm = cc.getDeclaredMethod(methodName);
// 
//             // 使用javaassist的反射方法获取方法的参数名
//             MethodInfo methodInfo = cm.getMethodInfo();
//             CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
//             LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
//             if (attr == null) {
//                 throw new RuntimeException("LocalVariableAttribute of method is null! Class " + clazz.getName() + ",method name is " + methodName);
//             }
//             String[] paramNames = new String[cm.getParameterTypes().length];
//             int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
//             for (int i = 0; i < paramNames.length; i++)
//                 paramNames[i] = attr.variableName(i + pos);
// 
//             return paramNames;
//         } catch (NotFoundException e) {
//             throw new RuntimeException(e.getMessage(), e);
//         }
//     }
// 
//     public static Class<?> getClass(String className) {
//         return classMap.computeIfAbsent(className, clazzName -> {
//             try {
//                 return Class.forName(clazzName);
//             } catch (ClassNotFoundException e) {
//                 throw new RuntimeException(e);
//             }
//         });
//     }
// 
//     public static void invoke(Object targetObject, Method method, Object[] objects) {
//         final Class<?> clazz = targetObject.getClass();
//         final FastClass fastClass = FastClass.create(clazz);
//         try {
//             fastClass.getMethod(method).invoke(targetObject, objects);
//         } catch (InvocationTargetException e) {
//             throw new RuntimeException(e);
//         }
//     }
// 
//     public static Optional<Method> getMethod(Class<?> clazz, String eventName, Predicate<Method> methodPredicate) {
//         final Method[] methods = clazz.getDeclaredMethods();
// 
//         return Arrays.stream(methods)
//                 .filter(method -> method.getName().equals(eventName))
//                 .filter(methodPredicate)
//                 .findAny();
//     }
// 
//     public static void main(String[] args) throws NotFoundException {
// 
//         String[] paramNames = ReflectUtil.getMethodArgNames(ReflectUtil.class, "add");
//         // paramNames即参数名
//         for (int i = 0; i < paramNames.length; i++) {
//             System.out.println(paramNames[i]);
//         }
//     }
// 
// }


// Path: koper-core/src/main/java/koper/MessageListenerBeanPostProcessor.java
import koper.client.ConsumerLauncher;
import koper.util.ReflectUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;

            // pojo listener
            final Listen listenAnnotation = bean.getClass().getAnnotation(Listen.class);
            final String topic = listenAnnotation.topic();
            if (StringUtils.isBlank(topic)) {
                throw new RuntimeException(
                        String.format("class %s, @Listen annotation topic not specified, please check", bean)
                );
            } else {
                registerListener(bean, topic);
            }
        }
        return bean;
    }

    /**
     * 注册消息监听器
     *
     * @param listener
     */
    protected void registerMsgBeanListener(MsgBeanListener listener) {

        Class<?> clazz = listener.getClass();
        Method method;
        String topic = null;
        Listen listen;
        method = getMethod(clazz, "onMsgBean");
        listen = method == null ? null : method.getAnnotation(Listen.class);

        if (listen == null) {
            // 先拿类上的 Listen 注解, 没有再拿方法上的Listen
            final Listen clazzAnnotation = ReflectUtil.getListenAnnotation(clazz);