JDK 动态代理 + 工厂设计模式

文件目录:

    proxy
      -- MockServiceProxy
      -- ServiceProxy
      -- ServiceProxyFactory

Mock 服务代理(JDK 动态代理):

/**
 * Mock 服务代理(JDK 动态代理)
 *
 * @author nami404
 * * @date 2024/6/27 12:13
 */
@Slf4j
public class MockServiceProxy implements InvocationHandler {
    /**
     * 调用代理
     *
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //根据方法的返回值类型,生成特定的默认值对象
        Class<?> methodReturnType = method.getReturnType();
        log.info("mock invoke {}", method.getName());
        return getDefaultObject(methodReturnType);
    }

    /**
     * 生成指定类型的默认值对象(可自行完善默认值逻辑)
     * @param type
     * @return
     */
    private Object getDefaultObject(Class<?> type) {
        // 基本类型
        if (type.isPrimitive()) {
            if (type == boolean.class) {
                return false;
            } else if (type == short.class) {
                return (short)0;
            } else if (type == int.class) {
                return 0;
            } else if (type == long.class) {
                return 0L;
            } else if (type == byte.class) {
                return 0;
            } else if (type == char.class) {
                return (char)0;
            } else if (type == float.class) {
                return 0f;
            } else if (type == double.class) {
                return 0d;
            }
        }
        // 对象类型
        return null;
    }
}

服务代理(JDK 动态代理):

/**
 * 服务代理(JDK 动态代理)
 *
 * @author nami404
 * * @date 2024/6/25 18:44
 */
public class ServiceProxy implements InvocationHandler {
    /**
     * 调用代理
     *
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //指定序列化器
        JdkSerializer serializer = new JdkSerializer();

        //构造请求
        RpcRequest rpcRequest = RpcRequest.builder()
                .serviceName(method.getDeclaringClass().getName())
                .methodName(method.getName())
                .parameterType(method.getParameterTypes())
                .args(args)
                .build();

        try {
            // 序列化
            byte[] bodyBytes = serializer.serialize(rpcRequest);
            // 发送请求
            // todo 注意,这里地址是硬编码(需要使用注册中心和服务发现机制解决)
            try (HttpResponse httpResponse = HttpRequest.post("http://localhost:8080")
                    .body(bodyBytes)
                    .execute()) {
                byte[] result = httpResponse.bodyBytes();
                // 反序列化
                RpcResponse rpcResponse = serializer.deserialize(result, RpcResponse.class);
                return rpcResponse.getData();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

服务代理工厂(用于创建代理对象):

/**
 * 服务代理工厂(用于创建代理对象)
 * @author nami404
 * * @date 2024/6/25 18:44
 */
public class ServiceProxyFactory {
    /**
     * 根据服务类获取代理对象
     *
     * @param serviceClass
     * @return
     * @param <T>
     */
    public static <T> T getProxy(Class<T> serviceClass) {
        if (RpcApplication.getRpcConfig().isMock()) {
            return getMockProxy(serviceClass);
        }
        return (T) Proxy.newProxyInstance(serviceClass.getClassLoader(), new Class[]{serviceClass}, new ServiceProxy());
    }

    /**
     * 根据服务类获取Mock 代理对象
     *
     * @param serviceClass
     * @return
     * @param <T>
     */
    public static <T> T getMockProxy(Class<T> serviceClass) {
        return (T) Proxy.newProxyInstance(
                serviceClass.getClassLoader(),
                new Class[]{serviceClass},
                new MockServiceProxy());
    }
}

实现流程:

对应的Proxy类需要实现接口 InvocationHandler 调用处理器,重写方法invoke 调用代理。

Proxy工厂类,新建实例,需要使用方法Proxy.newProxyInstance(A, B, C)

Proxy.newProxyInstance 是 Java 中于创建代理实例的方法。它位于java.lang.reflect包下。
Proxy.newProxyInstance有三个参数,分别是:

  1. ClassLoader 类加载器:用于加载代理类的类加载器。
  2. Class<?>[] 接口数组:代理类需要实现的接口数组。
  3. InvocationHandler 调用处理器:处理代理类方法的调用,即对方法的具体逻辑进行定义。
posted @ 2024-06-27 13:22  AI未来10Y  阅读(6)  评论(0编辑  收藏  举报