版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingyangV587/article/details/86507330
项目案例的结构
服务器端业务处理类
//服务器端业务处理类
public class InvokeHandler extends ChannelInboundHandlerAdapter {
//得到某接口下某个实现类的名字
private String getImplClassName(ClassInfo classInfo) throws Exception{
//服务方实现类所在的包路径
String interfacePath="com.gjy.rpc.server";
Class superClass=Class.forName(classInfo.getClassName());
Reflections reflections = new Reflections(interfacePath);
//得到某接口下的所有实现类
Set<Class> ImplClassSet=reflections.getSubTypesOf(superClass);
if(ImplClassSet.size()==0){
System.out.println("未找到实现类");
return null;
}else if(ImplClassSet.size()>1){
System.out.println("找到多个实现类,未明确使用哪一个");
return null;
}else {
//把集合转换为数组
Class[] classes=ImplClassSet.toArray(new Class[0]);
return classes[0].getName(); //得到实现类的名字
}
}
@Override //读取客户端发来的数据并通过反射调用实现类的方法
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ClassInfo classInfo = (ClassInfo) msg;
Object clazz = Class.forName(getImplClassName(classInfo)).newInstance();
Method method = clazz.getClass().getMethod(classInfo.getMethodName(), classInfo.getTypes());
//通过反射调用实现类的方法
Object result = method.invoke(clazz, classInfo.getObjects());
ctx.writeAndFlush(result);
}
}
客户端代理类
//客户端代理类
public class NettyRPCProxy {
// 根据接口创建代理对象
public static Object create(Class target) {
return Proxy.newProxyInstance(target.getClassLoader(), new Class[] { target }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 封装ClassInfo
ClassInfo classInfo = new ClassInfo();
classInfo.setClassName(target.getName());
classInfo.setMethodName(method.getName());
classInfo.setObjects(args);
classInfo.setTypes(method.getParameterTypes());
// 开始用Netty发送数据
EventLoopGroup group = new NioEventLoopGroup();
ResultHandler resultHandler = new ResultHandler();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 编码器
pipeline.addLast("encoder", new ObjectEncoder());
// 解码器 构造方法第一个参数设置二进制数据的最大字节数 第二个参数设置具体使用哪个类解析器
pipeline.addLast("decoder",
new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));
// 客户端业务处理类
pipeline.addLast("handler", resultHandler);
}
});
ChannelFuture future = b.connect("127.0.0.1", 9999).sync();
future.channel().writeAndFlush(classInfo).sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
return resultHandler.getResponse();
}
});
}
}
封装类信息
//封装类信息
public class ClassInfo implements Serializable {
private static final long serialVersionUID = 1L;
private String className; //类名
private String methodName;//方法名
private Class<?>[] types; //参数类型
private Object[] objects;//参数列表
//省略get set
}
写samples开始测试
接口定义
public interface HelloRPC {
String say(String name);
}
服务提供者
实现接口:
public String say(String name) {
return name;
}
开启服务:
public static void main(String[] args) throws Exception {
new RPCServer(9999).start();
}
服务消费者
public static void main(String[] args) {
HelloRPC helloRPC = (HelloRPC) NettyRPCProxy.create(HelloRPC.class);
System.out.println(helloRPC.say("RPC"));
}
完整案例下载:https://gitee.com/jingyang3877/all-examples/blob/master/jingyang3877-gjy-rpc-master.zip