DangerWind-RPC-framework---一、服务注册与发现

       服务的注册与发现借助Spring Bean的生命周期来完成。

       Spring Bean的生命周期的步骤中包含以下几步:调用aware接口、BeanPostProcessor 执行postProcessBeforeInitialization方法、BeanPostProcessor 执行postProcessAfterInitialization方法。现在需要利用这三个步骤来实现服务的注册与发现。

       为了完成服务的注册与发现,主要需要完成以下步骤:定义RPC服务(对应注解)的扫描包范围,装配RPC服务端服务的Bean到IOC容器当中;将服务发布到注册中心。这两步可以分别对应“调用aware接口、BeanPostProcessor 执行postProcessBeforeInitialization方法”。而“BeanPostProcessor 执行postProcessAfterInitialization方法这一步骤”可以用来生成并填充客户端动态代理类。

       首先设计注解RpcScan,其中定义包扫描范围。其中,Import注解是一个Spring提供的注解,用于导入一个或多个类到Spring容器中。这些类可以是配置类(带有@Configuration注解的类),也可以是实现了ImportSelector或ImportBeanDefinitionRegistrar接口的类(本次使用)。导入的类会被Spring容器处理,从而实现对Spring配置的扩展或自定义。@RpcScan注解定义时,通过@Import(CustomScannerRegistrar.class)引入CustomScannerRegistrar,意味着当任何一个Spring配置类上使用了@RpcScan注解,CustomScannerRegistrar也会被自动导入到Spring的配置中。这样,CustomScannerRegistrar的逻辑就会被执行,这通常涉及到自定义的扫描逻辑,比如扫描某些特定的注解,并将扫描到的类注册为Spring容器中的bean。只有标注了@RpcScan注解的类才会触发CustomScannerRegistrar中的逻辑。这是因为@RpcScan注解上使用了@Import(CustomScannerRegistrar.class),这意味着当Spring框架解析到某个类上使用了@RpcScan注解时,它会自动导入CustomScannerRegistrar类,并执行其中定义的逻辑。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Import(CustomScannerRegistrar.class)
@Documented
public @interface RpcScan {String[] basePackage();}

        注册Bean的CustomScannerRegistrar需要实现两个接口,ImportBeanDefinitionRegistrar和 ResourceLoaderAware,实现ResourceLoaderAware接口是为了获取ResourceLoader,以便加载资源(加载Bean)。实现ImportBeanDefinitionRegistrar允许在Spring容器启动时动态注册Bean定义。通过实现该接口,可以在运行时根据特定条件注册Bean,而不是在编译时静态定义。二者对应的setResourceLoader和registerBeanDefinitions都在BeanPostProcessor执行之前执行。

    @Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {this.resourceLoader = resourceLoader;}@Overridepublic void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {// RpcScan注解上获取的map键值对封装到AnnotationAttributes对象中AnnotationAttributes rpcScanAnnotationAttributes = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(RpcScan.class.getName()));String[] rpcScanBasePackages = new String[0];if (rpcScanAnnotationAttributes != null) {// 获取属性rpcScanBasePackages = rpcScanAnnotationAttributes.getStringArray(BASE_PACKAGE_ATTRIBUTE_NAME);}if (rpcScanBasePackages.length == 0) {// 没获取到,用注解所在包rpcScanBasePackages = new String[]{((StandardAnnotationMetadata) annotationMetadata).getIntrospectedClass().getPackage().getName()};}// 扫描RpcService annotationCustomScanner rpcServiceScanner = new CustomScanner(beanDefinitionRegistry, RpcService.class);// 扫描Component annotationCustomScanner springBeanScanner = new CustomScanner(beanDefinitionRegistry, Component.class);if (resourceLoader != null) {// 设置加载用的resourceLoaderrpcServiceScanner.setResourceLoader(resourceLoader);springBeanScanner.setResourceLoader(resourceLoader);}int springBeanAmount = springBeanScanner.scan(SPRING_BEAN_BASE_PACKAGE);log.info("springBeanScanner扫描的数量 [{}]", springBeanAmount);// 扫描到后会通过CustomScanner初始化时的beanDefinitionRegistry注册int rpcServiceCount = rpcServiceScanner.scan(rpcScanBasePackages);log.info("rpcServiceScanner扫描的数量 [{}]", rpcServiceCount);}

           CustomScanner继承自ClassPathBeanDefinitionScanner,封装了构造器支持扫描特定注解并使用BeanDefinitionRegistry进行注册:

public class CustomScanner extends ClassPathBeanDefinitionScanner {public CustomScanner(BeanDefinitionRegistry registry, Class<? extends Annotation> annoType) {super(registry);super.addIncludeFilter(new AnnotationTypeFilter(annoType));}@Overridepublic int scan(String... basePackages) {return super.scan(basePackages);}
}

       通过上述步骤将RPC服务端的实现类加载到了IOC容器中,接下来是向注册中心发起注册的过程,主要在BeanPostProcessor执行postProcessBeforeInitialization方法过程中实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/43236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态模型管理:Mojo模型的自定义保存与加载控制

动态模型管理&#xff1a;Mojo模型的自定义保存与加载控制 在机器学习模型的生命周期中&#xff0c;模型的保存与加载是一个至关重要的环节。Mojo模型&#xff0c;作为H2O.ai提供的一种模型部署格式&#xff0c;主要用于模型的序列化和预测。Mojo模型支持将训练好的模型转换为…

sql 清空表,并清空自增 id

执行 sql TRUNCATE 表名 表名替换为自己要清空的表 在 Navicat 中 新建查询输入 上述 sql点击运行即可表页 f5 刷新&#xff0c;数据已经清空&#xff0c;再次新增数据&#xff0c;自增 id 从 1 开始

Tomcat的负载均衡、动静分离

一、如何tomcat和nginx负载均衡及动静分离&#xff1a;2台tomcat&#xff0c;3台nginx来实现 1.首先设置tomcat1和tomcat2服务器 关闭两台tomcat的防火墙及安全机制&#xff1a;systemctl stop filwalld setenforce 0 进入tomcat目录的webapps中&#xff0c;创建test 2.配…

音频demo:使用opencore-amr将PCM数据与AMR-NB数据进行相互编解码

1、README a. 编译 编译demo 由于提供的.a静态库是在x86_64的机器上编译的&#xff0c;所以仅支持该架构的主机上编译运行。 $ make编译opencore-amr 如果想要在其他架构的CPU上编译运行&#xff0c;可以使用以下命令&#xff08;脚本&#xff09;编译opencore-amr[下载地…

【SpringBoot3】使用os-maven-plugin为项目自动添加常用的变量

一、什么是os-maven-plugin os-maven-plugin 是一个 Maven 扩展/插件&#xff0c;它根据 ${os.name} 和 ${os.arch} 生成各种有用的、与平台相关的项目属性&#xff0c;并将这些属性标准化。${os.name} 和 ${os.arch} 在不同的 JVM 和操作系统版本之间往往存在细微的差异&…

移除元素合并两个有序数组-LeetCode

一、移除元素 . - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; int removeElement(int* nums, int numsSize, int val) {int src0;int dst0;while(src<numsSize){if(nums[src]val){src;}else if (nums[src]!val){nums[dst]nums[src];src;dst;}}return dst…

渲染引擎之ECS架构介绍

1.什么是ECS&#xff1f; 我们先简单地介绍一下什么是ECS&#xff1a; E -- Entity 实体&#xff0c;本质上是存放组件的容器C -- Component 组件&#xff0c;引擎所需的所有数据结构S -- System 系统&#xff0c;根据组件数据处理逻辑状态的管理器 ECS全称Entity-Component-…

SAPUI5基础知识11 - 组件配置(Component)

1. 背景 组件&#xff08;Component&#xff09;是SAPUI5应用程序中独立且可重用的部件。 SAPUI5提供以下两类组件: faceless组件 (class: sap.ui.core.Component): 无界面组件即没有用户界面相关的元素&#xff0c;用于不需要UI元素编码的场景&#xff1b; UI组件 (class: …

C# 实现基于exe内嵌HTTPS监听服务、从HTTP升级到HTTPS 后端windows服务

由于客户需要把原有HTTP后端服务升级为支持https的服务&#xff0c;因为原有的HTTP服务是一个基于WINDOWS服务内嵌HTTP监听服务实现的&#xff0c;并不支持https, 也不像其他IIS中部署的WebAPI服务那样直接加载HTTPS证书&#xff0c;所以这里需要修改原服务支持https和服务器环…

每日复盘-20240708

今日关注: 20240708 六日涨幅最大: ------1--------300391--------- 长药控股 五日涨幅最大: ------1--------300391--------- 长药控股 四日涨幅最大: ------1--------300391--------- 长药控股 三日涨幅最大: ------1--------300391--------- 长药控股 二日涨幅最大: ------…

JAVA进阶学习11

文章目录 一、方法引用1.1 引用静态方法1.2 引用成员方法1.3 引用构造方法1.4 方法引用的其他调用方式1.4.1 使用类名引用成员方法1.4.2 引用数组的构造方法 1.5 总结二、异常2.1 异常的处理2.1.1 JVM虚拟机处理异常2.1.2 try...catch异常处理 2.2 异常中的常见方法2.3 异常的抛…

Java集合升序降序、转Set的方法

Collections.sort(list,Comparator.comparing(OcApplySquareVo::getApplyName).reversed()); 集合转set /** 集合转set */Set<String> pkCodeSet rows.stream().map(RailwayWeighBookResult.RailwayWeighBook::getPkCode).collect(Collectors.toSet());

互联网接入技术的简单介绍

引言 要连接到互联网&#xff0c;用户必须先连接到某个ISP&#xff08;互联网服务提供商&#xff09;。接入技术解决的就是用户如何连接到本地ISP的问题&#xff0c;通常称之为“最后一公里”。本文将详细介绍几种主要的互联网接入技术&#xff0c;帮助初学者了解不同的接入方…

【SOM神经网络的数据分类】SOM神经网络的数据分类的一个小案例

【SOM神经网络的数据分类】SOM神经网络的数据分类的一个小案例 注&#xff1a;本文仅作为自己的学习记录以备以后复习查阅 一 概述 自组织特征映射网络&#xff08;Self-Organizing Feature Map, SOM&#xff09;也叫做Kohonen网络&#xff0c;它的特点是&#xff1a;全连接、…

Android 列表视频滑动自动播放—滑动过程自动播放(实现思路)

本文基于Exoplayer PlayerView 实现列表视频显示一定比例后自动播放 首先引入google media3包 implementation androidx.media3:media3-exoplayer:1.1.1 implementation androidx.media3:media3-exoplayer-dash:1.1.1 implementation androidx.media3:media3-ui:1.1.1 impl…

【C++深度探索】继承机制详解(二)

hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1…

Redis排行榜

long 整数长度总共有 19位&#xff0c;923XXX…&#xff0c;时间戳 毫秒精度 是 13位&#xff0c;所以只需 14 ~ 19 位存 等级&#xff0c;其他13位存时间。接下来看怎么存。 等级偏移&#xff1a; Math.power(10, 14) 10000000000000000&#xff08;14位&#xff09; 这里有一…

如何把已经上传到gitlab的代码或者文件夹从git上删掉

有小伙伴不小心把缓存文件上传到了git&#xff0c;跑来问我&#xff0c;要怎么把这些文件给删掉&#xff0c;这里一共有两种方式&#xff0c; 先说第一种&#xff0c;通过命令删除&#xff0c;终端进入存在这个缓存文件的目录&#xff0c;执行命令ls&#xff0c;可以看到确实有…

[C++][ProtoBuf][Proto3语法][二]详细讲解

目录 1.Any类型1.说明2.代码&使用 2.oneof类型1.说明2.代码&使用 3.map类型1.说明2.代码&使用 1.Any类型 1.说明 字段还可以声明为Any类型&#xff0c;可以理解为泛型类型 使⽤时可以在Any中存储任意消息类型 父类是Message Any类型的字段也可以⽤repeated来修饰…

从零开始搭建vite开发环境

准备 nodejs 18 pnpm https://vitejs.cn/ 开始 pnpm init pnpm add -D vite新建index.html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width…