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有三个参数,分别是:
- ClassLoader 类加载器:用于加载代理类的类加载器。
- Class<?>[] 接口数组:代理类需要实现的接口数组。
- InvocationHandler 调用处理器:处理代理类方法的调用,即对方法的具体逻辑进行定义。