# RPC框架 **Repository Path**: hb_study/rpc_io ## Basic Information - **Project Name**: RPC框架 - **Description**: 自定义 RPC框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-06-03 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 部署 - 把自定义rpc框架jar打入maven本地仓库 ![image-20200609230938339]( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200609230938339.png) - 客户端和服务端引用jar ![image-20200609231026606]( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200609231026606.png) ```groovy implementation 'com.hb.study.io:rpc_framework:1.0-SNAPSHOT' ``` - 服务端配置 ```java /** * 配置服务端 * * @return com.hb.study.rpc.framework.server.StartServer * @author bo.huang update * @date 2020/6/9 10:14 下午 */ @Bean public StartServer getStartServer() throws InterruptedException { StartServer startServer = new StartServer(); startServer.setApplicationContext(applicationContext); startServer.start("127.0.0.1", 9092); return startServer; } ``` - 客户端启动配置 ```java /** * 客户端配置 * * @return com.hb.study.rpc.framework.client.StartClient * @author bo.huang update * @date 2020/6/9 10:13 下午 */ @Bean public StartClient getStartClient() throws InterruptedException { StartClient client = new StartClient("127.0.0.1", 9092); client.start(); return client; } ``` ### 效果 分别启动服务端与客户端,访问路径 http://localhost:19091/test ![image-20200609231237829]( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200609231237829.png) http://localhost:19091/test1 ![image-20200609231303037]( https://typora-hb.oss-cn-shanghai.aliyuncs.com/typera/image-20200609231303037.png) ### 配置 - 在序列化与反序列化中.我没有用fastjson的写的,因为它在序列化出现一个问题,Object数组,我传入Long型,反序列化有转为Int类型,所以我自定义的JDK的序列化 - 自定义注解,扫描class加载到spring容器中 ```java /** * RPC服务端注解 * * @author bo.huang * @since 2020/6/4 4:22 下午 */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) public @interface Service { } ``` ```java /** * @author bo.huang * @since 2020/6/4 5:01 下午 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @Import({ServiceAutoConfigureRegistrar.class}) public @interface ServiceScan { String[] value() default ""; } ``` ```java package com.hb.study.rpc.framework.spring; import com.hb.study.rpc.framework.annotaion.Service; import com.hb.study.rpc.framework.annotaion.ServiceScan; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.core.type.filter.AnnotationTypeFilter; /** * 定义ImportBeanDefinitionRegistrar的实现类ServiceAutoConfigureRegistrar。如果需要获取Spring中的一些数据,可实现一些Aware接口,这实现了ResourceLoaderAware。 * * @author bo.huang * @since 2020/6/4 4:23 下午 */ public class ServiceAutoConfigureRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware { private ResourceLoader resourceLoader; private String[] basePackages; // public ServiceAutoConfigureRegistrar(String... basePackages) { // this.basePackages = basePackages; // } @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { StandardAnnotationMetadata standardAnnotationMetadata = (StandardAnnotationMetadata) importingClassMetadata; ServiceScan serviceScan = standardAnnotationMetadata.getIntrospectedClass().getAnnotation(ServiceScan.class); if (serviceScan == null || serviceScan.value()[0].length() <= 0) { throw new RuntimeException("RPC service扫描路径未配置"); } ServiceBeanDefinitionScanner scanner = new ServiceBeanDefinitionScanner(registry, false); scanner.setResourceLoader(resourceLoader); scanner.registerFilters(); scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class)); scanner.doScan(serviceScan.value()); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } } ``` ```java package com.hb.study.rpc.framework.spring; import com.hb.study.rpc.framework.annotaion.Service; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ClassPathBeanDefinitionScanner; import org.springframework.core.type.filter.AnnotationTypeFilter; import java.util.Set; /** * @author bo.huang * @since 2020/6/4 4:24 下午 */ public class ServiceBeanDefinitionScanner extends ClassPathBeanDefinitionScanner { public ServiceBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { super(registry, useDefaultFilters); } /** * 注册bean拦截器 * * @author bo.huang update * @date 2020/6/4 4:26 下午 */ protected void registerFilters() { addIncludeFilter(new AnnotationTypeFilter(Service.class)); } /** * 扫描bean路径 * * @param basePackages basePackages * @return java.util.Set * @author bo.huang update * @date 2020/6/4 4:26 下午 */ @Override protected Set doScan(String... basePackages) { return super.doScan(basePackages); } } ```