手写RPC框架优化(一)

mac2025-04-06  16

上次手写了一个简单的RPC框架,这次对其进行优化升级,添加了版本号,利用Spring进行管理,详细修改过程请看代码。 首先在rpc-server-provider模块下pom文件导入Spring依赖。

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.24.RELEASE</version> </dependency>

自定义一个注解,用于接收类与版本号。

@Target(ElementType.TYPE)//修饰的是类或者接口 对象范围 @Retention(RetentionPolicy.RUNTIME)//保留到运行时 @Component//被Spring进行扫描 public @interface RpcService { Class<?> value();//服务的类与接口 String version() default ""; }

为HelloServiceImpl加上注解

@RpcService(value = IHelloService.class,version = "v1.0") public class HelloServiceImpl implements IHelloService { @Override public String sayHello(String content) { System.out.println("{v1.0}request in sayHello:"+content); return "Say Hellp: "+content; } @Override public String saveUser(User user) { System.out.println("{v1.0}request in SaveUser:"+user.toString()); return "SUCCESS"; } }

新建YbRpcServer实现ApplicationContextAware、InitializingBean 接口用来处理接口传递的信息与bean的初始化过程。

@Component public class YbRpcServer implements ApplicationContextAware, InitializingBean { ExecutorService executorService= Executors.newCachedThreadPool(); private int port; private Map<String,Object> handlerMap=new HashMap<>();//用来存储对应Bean public YbRpcServer(int port) { this.port = port; } @Override public void afterPropertiesSet() { ServerSocket serverSocket=null; try { serverSocket = new ServerSocket(port); while (true){ Socket socket= serverSocket.accept(); //每个Socker 交给一个ProcessorHandler来处理 executorService.execute(new ProcessorHandler(socket,handlerMap)); } } catch (IOException e) { e.printStackTrace(); }finally { if(serverSocket!=null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map<String,Object> serviceBeanMap=applicationContext.getBeansWithAnnotation(RpcService.class); if(!serviceBeanMap.isEmpty()){ for (Object serviceBean:serviceBeanMap.values()){ //拿到注解 RpcService rpcService= serviceBean.getClass().getAnnotation(RpcService.class); String serviceName = rpcService.value().getName();//拿到接口类 String version =rpcService.version();//拿到版本号 if(!StringUtils.isEmpty(version)){ serviceName+="-"+version; } handlerMap.put(serviceName,serviceBean); } } } }

新建类SpringConfig用于将类交予Spring管理

@Configuration @ComponentScan(basePackages ="com.rpc" ) public class SpringConfig { @Bean(name = "ybRpcServer") public YbRpcServer ybRpcServer(){ return new YbRpcServer(8080); } }

修改RpcRequest中传递版本号。

public class RpcRequest implements Serializable { private String className; private String methodName; private Object[] parameters; private String version;

接下来改一下服务器启动方式,大功告成。记得在客户端传递版本号。

public class App { public static void main(String[] args) { // IHelloService helloService=new HelloServiceImpl(); // RpcProxyServer proxyServer=new RpcProxyServer(); // proxyServer.publisher(helloService,8080); ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class); ((AnnotationConfigApplicationContext)context).start(); } }

后续如果有空可以利用NIO优化下IO问题目前还是BIO的模型。

最新回复(0)