基于JAVA的RPC简单实现。
一、RPC是什么?
RPC即Remote Procedure Call 是一种进程间通信方式。RPC是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议,是分布式系统常见的一种通信方法。RPC采用客户机/服务器模式。
二、RPC框架结构图
二、RPC框架流程图
四、代码实现
1.rpc-framework(父项目)
pom.xml文件,引入依赖。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wc</groupId>
<artifactId>rpcProject-framework</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<modules>
<module>rpc-common</module>
<module>rpc-proto</module>
<module>rpc-codec</module>
<module>rpc-transport</module>
<module>rpc-server</module>
<module>rpc-client</module>
<module>rpc-example</module>
</modules>
<!--版本管理-->
<properties>
<junit.version>4.13</junit.version>
<lombok.version>1.18.8</lombok.version>
<slf4j-api.version>1.7.26</slf4j-api.version>
<logback-classic.version>1.2.3</logback-classic.version>
<commons-io.version>2.5</commons-io.version>
<jetty-servlet.version>9.4.28.v20200408</jetty-servlet.version>
<fastjson.version>1.2.62</fastjson.version>
<java.version>1.8</java.version>
</properties>
<!--通用的依赖-->
<dependencies>
<!--测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!--lombok插件是为了方便实体类bean快速生成get set方法,从而不用手动添加-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
</dependencies>
<!--子项目中可能用到的依赖-->
<dependencyManagement>
<dependencies>
<!-- dubbo相关依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.5.4</version>
</dependency>
<!--处理io流的工具-->
<dependency>
<groupId>common-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
<!-- <version>${commons-io.version}</version>-->
</dependency>
<!--服务器jetty-->
<dependency>
<groupId>org.eclipose.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty-servlet.version}</version>
</dependency>
<!--序列化-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!---->
<build>
<plugins>
<!--通过 maven-compiler-plugin 插件来对 Java 代码编译的-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${java.version}</source> <!-- 源代码使用的JDK版本 -->
<target>${java.version}</target> <!-- 需要生成的目标class文件的编译版本 -->
<encoding>UTF-8</encoding><!-- 字符集编码 -->
</configuration>
</plugin>
</plugins>
</build>
</project>
2.rpc-common(公共模块)
ReflectionUtils(反射工具类)
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
/**
* 反射工具类
*/
@Slf4j
public class ReflectionUtils {
/**
* 根据传入的Class创建相应的对象
* @param clazz 待创建对象的类
* @param <T> 对象类型
* @return 创建的对象
*/
public static <T> T newInstance(Class<T> clazz) throws Exception{
try{
return clazz.newInstance();
}catch (Exception e){
log.error(e.getMessage(),e);
throw new IllegalStateException(e);
}
}
/**
* 获取传入类自有的公共方法
* @param clazz 传入类
* @return 传入类自有的公共方法
* @throws Exception
*/
public static Method[] getPublicMethods(Class clazz)throws Exception{
try{
//调用getMethods方法输出的是自身的public方法和父类Object的public方法
//调用getDeclaredMethods方法输出的是自身的public、protected、private方法
Method[] methods=clazz.getDeclaredMethods();
ArrayList<Method> list=new ArrayList<>();
for(Method m:methods){
//用Modifier类的函数来判断它是否属被某个修饰符修饰
//用getModifiers()得到了类(或者字段、或者方法)的访问修饰符int值
if(Modifier.isPublic(m.getModifiers())){
list.add(m);
}
}
return list.toArray(new Method[0]);
}catch (Exception e){
log.error(e.getMessage(),e);
throw new IllegalStateException(e);
}
}
/**
* 调用传入对象的传入方法(静态方法obj传null)
* @param obj 传入对象
* @param method 待调用方法
* @param args 传入参数
* @return
* @throws Exception
*/
public static Object invoke(Object obj,Method method,Object... args)throws Exception{
try{
return method.invoke(obj,args);
}catch (Exception e){
log.error(e.getMessage(),e);
throw new IllegalStateException(e);
}
}
}