All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.enodeframework.infrastructure.impl.AbstractHandlerProvider Maven / Gradle / Ivy

There is a newer version: 1.1.10
Show newest version
package org.enodeframework.infrastructure.impl;

import org.enodeframework.annotation.Command;
import org.enodeframework.annotation.Event;
import org.enodeframework.annotation.Priority;
import org.enodeframework.annotation.Subscribe;
import org.enodeframework.common.container.IObjectContainer;
import org.enodeframework.common.exception.HandlerRegisterException;
import org.enodeframework.common.utilities.Ensure;
import org.enodeframework.infrastructure.IAssemblyInitializer;
import org.enodeframework.infrastructure.IObjectProxy;
import org.enodeframework.infrastructure.MethodInvocation;
import org.enodeframework.messaging.MessageHandlerData;
import org.reflections.ReflectionUtils;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public abstract class AbstractHandlerProvider implements IAssemblyInitializer {
    private final Map> handlerDict = new HashMap<>();
    private final Map> messageHandlerDict = new HashMap<>();
    private final MethodHandles.Lookup lookup = MethodHandles.lookup();

    protected abstract TKey getKey(Method method);

    protected abstract Class getHandlerProxyImplementationType();

    protected abstract boolean isHandlerSourceMatchKey(THandlerSource handlerSource, TKey key);

    protected abstract boolean isHandleMethodMatch(Method method);

    protected abstract IObjectContainer getObjectContainer();

    @Override
    public void initialize(Set> componentTypes) {
        componentTypes.stream().filter(this::isHandlerType).forEach(this::registerHandler);
        initializeHandlerPriority();
    }

    public List> getHandlers(THandlerSource source) {
        List> handlerDataList = new ArrayList<>();
        messageHandlerDict.keySet().stream()
                .filter(key -> isHandlerSourceMatchKey(source, key))
                .forEach(key -> handlerDataList.add(messageHandlerDict.get(key)));
        return handlerDataList;
    }

    private void initializeHandlerPriority() {
        handlerDict.forEach((key, handlers) -> {
            MessageHandlerData handlerData = new MessageHandlerData<>();
            List listHandlers = new ArrayList<>();
            Map queueHandlerDict = new HashMap<>();
            handlers.forEach(handler -> {
                int priority = getHandleMethodPriority(handler);
                if (priority == 0) {
                    listHandlers.add(handler);
                } else {
                    queueHandlerDict.put(handler, priority);
                }
            });
            handlerData.allHandlers = handlers;
            handlerData.listHandlers = listHandlers;
            handlerData.queuedHandlers = queueHandlerDict.entrySet()
                    .stream()
                    .sorted(Comparator.comparingInt(Map.Entry::getValue))
                    .map(Map.Entry::getKey).collect(Collectors.toList());
            messageHandlerDict.put(key, handlerData);
        });
    }

    private int getHandleMethodPriority(THandlerProxyInterface handler) {
        Method method = handler.getMethod();
        int priority = 0;
        Priority methodPriority = method.getAnnotation(Priority.class);
        if (methodPriority != null) {
            priority = methodPriority.value();
        }
        if (priority == 0) {
            Priority classPriority = handler.getInnerObject().getClass().getAnnotation(Priority.class);
            if (classPriority != null) {
                priority = classPriority.value();
            }
        }
        return priority;
    }

    private boolean isHandlerType(Class type) {
        if (type == null) {
            return false;
        }
        if (type.isInterface()) {
            return false;
        }
        if (Modifier.isAbstract(type.getModifiers())) {
            return false;
        }
        return containsHandleType(type);
    }

    private boolean containsHandleType(Class type) {
        return type.isAnnotationPresent(Command.class) || type.isAnnotationPresent(Event.class);
    }

    protected boolean isMethodAnnotationSubscribe(Method method) {
        return method.isAnnotationPresent(Subscribe.class);
    }

    private void registerHandler(Class handlerType) {
        Set handleMethods = ReflectionUtils.getMethods(handlerType, this::isHandleMethodMatch);
        handleMethods.forEach(method -> {
            try {
                // 反射Method转换为MethodHandle,提高效率
                MethodHandle handleMethod = lookup.findVirtual(handlerType, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()));
                TKey key = getKey(method);
                List handlers = handlerDict.computeIfAbsent(key, k -> new ArrayList<>());
                IObjectContainer objectContainer = getObjectContainer();
                Ensure.notNull(objectContainer, "objectContainer");
                THandlerProxyInterface handlerProxy = objectContainer.resolve(getHandlerProxyImplementationType());
                Ensure.notNull(handlerProxy, String.format("handlerProxy: %s", getHandlerProxyImplementationType().getName()));
                handlerProxy.setHandlerType(handlerType);
                handlerProxy.setMethod(method);
                handlerProxy.setMethodHandle(handleMethod);
                handlers.add(handlerProxy);
            } catch (Exception e) {
                throw new HandlerRegisterException(e);
            }
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy