系统架构


一些问题
程序入口:
@RpcScan给开发者用的,对于server侧,开发者在主启动类上标注这个,指定一个路径,框架就会去扫描这个路径及其子路径下的所有被@RpcService标注的类(即暴露的RPC实现类),将其加载到spring容器中:
那👆🏻代码为何不都直接都用@Component呢:1.开发者便于识别,看到@RpcService就知道这个bean与普通的@Component不一样,它是对外提供的RPC服务!;2.在spring初始化操作的过程中容易对该bean有一些特殊的操作,可将其发布到zookeeper中:
发布到zookeeper中的结果都存放在my-rpc根节点下面,格式为全类名+group+version:
client调用远程服务时、server注册的时候,都需指定version和group,version区分迭代版本,group区分该接口的多个实现类。

再来看看这段代码,重点放在第一个方法的分析上:
/*** call this method before creating the bean to see if the class is annotated** @author shuang.kou* @createTime 2020年07月14日 16:42:00*/@Slf4j@Componentpublic class SpringBeanPostProcessor implements BeanPostProcessor {private final ServiceProvider serviceProvider;private final RpcRequestTransport rpcClient;public SpringBeanPostProcessor() {this.serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);this.rpcClient = ExtensionLoader.getExtensionLoader(RpcRequestTransport.class).getExtension("netty");}@SneakyThrows@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean.getClass().isAnnotationPresent(RpcService.class)) {log.info("[{}] is annotated with [{}]", bean.getClass().getName(), RpcService.class.getCanonicalName());// get RpcService annotationRpcService rpcService = bean.getClass().getAnnotation(RpcService.class);// build RpcServicePropertiesRpcServiceConfig rpcServiceConfig = RpcServiceConfig.builder().group(rpcService.group()).version(rpcService.version()).service(bean).build();serviceProvider.publishService(rpcServiceConfig);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {Class<?> targetClass = bean.getClass();Field[] declaredFields = targetClass.getDeclaredFields();for (Field declaredField : declaredFields) {RpcReference rpcReference = declaredField.getAnnotation(RpcReference.class);if (rpcReference != null) {RpcServiceConfig rpcServiceConfig = RpcServiceConfig.builder().group(rpcReference.group()).version(rpcReference.version()).build();RpcClientProxy rpcClientProxy = new RpcClientProxy(rpcClient, rpcServiceConfig);Object clientProxy = rpcClientProxy.getProxy(declaredField.getType());declaredField.setAccessible(true);try {declaredField.set(bean, clientProxy);} catch (IllegalAccessException e) {e.printStackTrace();}}}return bean;}}
在分析第一个方法之前,可以先分析一下项目结构:此类属于rpc-framework-simple这个模块,也就是
