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

com.hyf.hotrefresh.remoting.rpc.RpcMessageFactory Maven / Gradle / Ivy

package com.hyf.hotrefresh.remoting.rpc;

import com.hyf.hotrefresh.common.util.ReflectionUtils;
import com.hyf.hotrefresh.common.util.TypeUtils;
import com.hyf.hotrefresh.remoting.exception.RpcException;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author baB_hyf
 * @date 2022/05/18
 */
public class RpcMessageFactory {

    private static final Map>, Class> cache = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static  T createRpcMessage(byte messageTypeCode) {
        RpcMessageHandler handler = RpcMessageHandlerRegistry.getInstance().getHandler(messageTypeCode);

        if (handler == null) {
            throw new RpcException("Unknown message type code: " + messageTypeCode);
        }

        Class clazz = getRpcMessageClassType((Class>) handler.getClass());
        return ReflectionUtils.newClassInstance(clazz);
    }

    @SuppressWarnings("unchecked")
    public static  Class getRpcMessageClassType(
            Class> clazz) {
        Class messageClass = (Class) cache.compute(clazz, (h, m) -> {

            if (m == null) {
                List allGenericTypes = TypeUtils.getAllGenericTypes(clazz);
                for (ParameterizedType parameterizedType : allGenericTypes) {
                    Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
                    if (actualTypeArgument instanceof Class) { // 泛型是个Class,表示固定的
                        Class requestType = (Class) actualTypeArgument;
                        boolean messageTypeValid =
                            RpcMessage.class.isAssignableFrom(requestType) && requestType != RpcMessage.class;
                        Type rawType = parameterizedType.getRawType();
                        boolean handlerTypeValid =
                            rawType instanceof Class && RpcMessageHandler.class.isAssignableFrom((Class) rawType);
                        if (messageTypeValid && handlerTypeValid) {
                            return requestType;
                        }
                    }
                }
            }

            if (m == null) {
                throw new RuntimeException("Handler class signature is illegal: " + clazz.getName());
            }

            return m;
        });

        return messageClass;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy