微服务-java spi 与 dubbo spi
Java SPI
通过一个案例来看SPI
public interface DemoSPI {void echo();
}
public class FirstImpl implements DemoSPI{@Overridepublic void echo() {System.out.println("first echo");}
}
public class SecondImpl implements DemoSPI{@Overridepublic void echo() {System.out.println("second echo");}
}
public class Main {public static void main(String[] args) {ServiceLoader<DemoSPI> loader = ServiceLoader.load(DemoSPI.class);Iterator<DemoSPI> iterator = loader.iterator();while (iterator.hasNext()) {iterator.next().echo();}System.out.println("加载完毕!!!!!");}
}
SPI :Service Provider Interface, 服务提供接口。
JDK SPI:ServiceLoader.load
使用load方法频率高,容易影响IO吞吐和内存消耗, 可以看到回去静态资源目录下读取文件。
使用load方法想要获取指定的实现类,需要自己进行遍历并编写各种比较代码,可能实现有多个所以需要比对。
Dubbo SPI: ApplicationModel.defaultModel().getExtensionLoader
增加缓存,来降低磁盘IO访问及减少对象的生成
使用Map的hash查找,来提升检索指定实现类的性能。
@SPI
public interface DubboSPI {void echo();
}
public class DubboFirstSPI implements DubboSPI{@Overridepublic void echo() {System.out.println("first dubbo spi");}
}
public class DubboSecondSPI implements DubboSPI{@Overridepublic void echo() {System.out.println("second spi");}
}public class DubboMain {public static void main(String[] args) {ExtensionLoader<DubboSPI> loader = ExtensionLoader.getExtensionLoader(DubboSPI.class);DubboSPI firstf = loader.getExtension("first");DubboSPI second = loader.getExtension("second");firstf.echo();second.echo();}
}
com.liyong.leran.dubbospi.DubboSPI里面的内容:
first=com.liyong.leran.dubbospi.DubboFirstSPI
second=com.liyong.leran.dubbospi.DubboSecondSPI
public T getExtension(String name, boolean wrap) {if (StringUtils.isEmpty(name)) {throw new IllegalArgumentException("Extension name == null");}if ("true".equals(name)) {return getDefaultExtension();}final Holder<Object> holder = getOrCreateHolder(name);Object instance = holder.get();if (instance == null) {synchronized (holder) {instance = holder.get();if (instance == null) {instance = createExtension(name, wrap);holder.set(instance);}}}return (T) instance;}
// 走缓存的方法
private Holder<Object> getOrCreateHolder(String name) {Holder<Object> holder = cachedInstances.get(name);if (holder == null) {cachedInstances.putIfAbsent(name, new Holder<>());holder = cachedInstances.get(name);}return holder;}
相关文章:

微服务-java spi 与 dubbo spi
Java SPI 通过一个案例来看SPI public interface DemoSPI {void echo(); } public class FirstImpl implements DemoSPI{Overridepublic void echo() {System.out.println("first echo");} } public class SecondImpl implements DemoSPI{Overridepublic void ech…...

redis复习笔记03(小滴课堂)
Redis6常见数据结构概览 0代表存在,1代表不存在。 1表示删除成功,0表示失败。 查看类型,默认string类型。 也可以设置set类型。 list类型。 查看key的过期时间: Redis6数据结构之String类型介绍和应用场景 批量设置: …...

【Spring Cloud】关于Nacos配置管理的详解介绍
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Spring Cloud》。🎯🎯 &am…...

基于Java SSM框架实现校园网络维修系统项目【项目源码】
基于java的SSM框架实现校园网络维修系统演示 java简介 Java主要采用CORBA技术和安全模型,可以在互联网应用的数据保护。它还提供了对EJB(Enterprise JavaBeans)的全面支持,java servlet API,JSP(java serve…...

项目框架构建之3:Nuget服务器的搭建
本文是“项目框架构建”系列之3,本文介绍一下Nuget服务器的搭建,这是一项简单的工作,您或许早已会了。 1.打开vs2022创建Asp.net Web应用程序 框架选择.net framework4.8,因为nuget服务器只支持.net framework。 2.选择空项目和保…...

外包干了1个月,技术退步一大半。。。
先说一下自己的情况,本科生,19年通过校招进入广州某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
167. 木棒(dfs剪枝,经典题)
167. 木棒 - AcWing题库 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 50 个长度单位。 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度。 请你设计一个程序࿰…...

用HTML的原生语法实现两个div子元素在同一行中排列
代码如下: <div id"level1" style"display: flex;"><div id"level2-1" style"display: inline-block; padding: 10px; border: 1px solid #ccc; margin: 5px;">这是第一个元素。</div><div id"…...

C++进阶--map和set的介绍及使用
map和set的介绍及使用 一、关联式容器与键值对关联式容器键值对pair树形结构的关联式容器 二、set2.1 set的介绍2.2 set的使用2.2.1 set的模板参数列表2.2.2 set的构造2.2.3 set的迭代器2.2.4 set的容量2.2.5 set修改操作2.2.6 set的使用举例 三、multiset3.1 multiset的介绍3.…...

MIML-DA
图3呢?且作者未提供代码...

[ROS2 Foxy]#1.3 安装使用 turtlesim
官网教程: https://docs.ros.org/en/foxy/Tutorials/Turtlesim/Introducing-Turtlesim.html 1.turtlesim安装和使用 turtlesim是一个轻量级的模拟程序,用来学习ROS2 .通过turtlesim来介绍ROS2在一个基础的水平上都要做了那些事,以此让我们了解将来在真的 robot或者模拟器上使用…...

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第三天-Linux进程(物联技术666)
更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…...

1-01初识C语言
一、概述 C语言是贝尔实验室的Ken Thompson(肯汤普逊)、Dennis Ritchie(丹尼斯里奇)等人开发的UNIX 操作系统的“副产品”,诞生于1970年代初。 Thompson和Ritchie共同创作完成了Unix操作系统,他们都被称为…...
Python字符串
定义字符串 Python中要定义一个字符串,有比较多的一种方式。 示例代码: s "你好,张大鹏" print(s, type(s))s 你好,张大鹏 print(s, type(s))s """你好,张大鹏""" prin…...

PHP 基础编程 1
文章目录 前后端交互尝试php简介php版本php 基础语法php的变量前后端交互 - 计算器体验php数据类型php的常量和变量的区别php的运算符算数运算符自增自减比较运算符赋值运算符逻辑运算 php的控制结构ifelseelse if 前后端交互尝试 前端编程语言:JS (Java…...

Android studio BottomNavigationView 应用设计
一、新建Bottom Navigation Activity项目: 二、修改bottom_nav_menu.xml: <itemandroid:id="@+id/navigation_beijing"android:icon="@drawable/ic_beijing_24dp"android:title="@string/title_beijing" /><itemandroid:id="@+i…...

51单片机串行口相关知识
51单片机串行口相关知识 串行通信概念 计算机与外部通信方式就两种: 并行通信串行通信 两种通信方式的特点以及适用场景: 名称特点适用场景并行通信速度快,效率高,成本高适合短距离高速通信,如计算机内部各硬件之…...

IDEA 每次新建工程都要重新配置 Maven的解决方案
文章目录 IDEA 每次新建工程都要重新配置 Maven 解决方案一、选择 File -> New Projects Setup -> Settingsfor New Projects…二、选择 Build,Execution,Deployment -> Build Tools -> Maven IDEA 每次新建工程都要重新配置 Maven 解决方案 DEA 每次新建工程都要…...

SecOC中新鲜度值和MAC都按照完整的值来生成,但是在发送和认证的时候只会截取一部分。这边截取的部分一般取多长?由什么参数设定?
新鲜度值(Freshness Value, FV)和消息验证码(Message Authentication Code, MAC)是SecOC协议中用于保证数据的真实性和新鲜度的重要信息。它们的长度取决于不同的因素,如加密算法、安全级别、通信带宽等。 一般来说,FV和MAC的长度越长,安全性越高,但也会占用更多的通信…...

信源编码与信道转移矩阵
目录 一. 信息论模型 二. 点对点通信模型 三. 信源编码 四. 信道转移矩阵 4.1 二进制对称信道 4.2 二进制擦除信道 五. 小结 (1)信道直射与反射 (2)信道散射 (3) 信道时变性 一. 信息论模型 194…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...