当前位置: 首页 > news >正文

常平网站建设关键词资源

常平网站建设,关键词资源,公司网站建设服务公司,济南做网站互联网公司排名1. 概述 SPI(Service Provider Interface),是 Java 6 引入了一个内置功能,实现服务提供发现和加载机制,使之与特定接口的匹配。 SPI 机制的核心思想就是 解耦 ,将装配的控制权移到程序之外,这…

1. 概述

SPI(Service Provider Interface),是 Java 6 引入了一个内置功能,实现服务提供发现和加载机制,使之与特定接口的匹配。

SPI 机制的核心思想就是 解耦 ,将装配的控制权移到程序之外,这在企业模块化设计中非常重要。

有的人喜欢拿 SPIAPI 之间做比较,关于二者之间的差异主要在于侧重点不一样。

  • API :侧重 调用 并用于实现目标的类、接口、方法等的描述;
  • SPI :侧重对已实现目标类、接口、方法的 扩展和实现

20230808170610

2. 使用场景

调用者根据实际使用需要,启用、扩展、或者替换框架的实现策略。

  • 数据库驱动加载接口实现类的加载: JDBC 加载不同类型数据库的驱动

  • 日志门面接口实现类加载:SLF4J 加载不同提供商的日志实现类

  • Spring 框架:Spring 中大量使用 SPI ,比如:对 Servlet3.0 规范对 ServletContainerInitializer 的实现、自动类型转换 Type Conversion SPI(Converter SPI、Formatter SPI)

3. 入门使用介绍

在实际使用 SPI 需要遵循以下约定:

  • 按照定义创建加载文件:当服务提供者提供了接口的一种具体实现后,在 jar 包的 META-INF/services 目录下创建一个以 接口全限定名为命名的文件,内容为实现类的全限定名;
  • 动态加载:主程序通过 java.util.ServiceLoder 动态装载实现模块,它通过扫描 META-INF/services 目录下的配置文件找到实现类的全限定名,把类加载到 JVM
  • 无参构造方法: SPI实现类必须携带一个不带参数的构造方法;
  • 相同classpath:接口实现类所在的 jar 包放在主程序的 classpath中;

4. 示例

4.1. 构建接口

此处演示作用,只定义一组接口,接口为 灵长类 动物,它包含一个方法, 叫 动作


package io.github.rothschil.spi.framework;/*** 灵长类动物* @author <a href="mailto:WCNGS@QQ.COM">Sam</a>* @version 1.0.0*/
public interface Primate {void action();
}

4.2. 拓展实现

灵长类 这个接口,我们假定它的实现为人类 、猴子,它们都能有属于自己的动物。

  • 人类

package io.github.rothschil.spi.framework.impl;import io.github.rothschil.spi.framework.Primate;public class Human implements Primate {@Overridepublic void action() {System.out.println("Human");}
}
  • 猴子

package io.github.rothschil.spi.framework.impl;import io.github.rothschil.spi.framework.Primate;public class Monkey implements Primate {@Overridepublic void action() {System.out.println("Monkey");}
}

4.3. 构建META-INF下文件

  • 文件路径: resources/META-INF/services
  • 文件名: io.github.rothschil.spi.framework.Primate
  • 文件内容:

io.github.rothschil.spi.framework.impl.Human
io.github.rothschil.spi.framework.impl.Monkey

4.4. 验证

此处用到 ServiceLoader 类加载器,通过 Primate.class 将它的实现以此加载到 JVM 中。

4.5. 结果

验证结果


package io.github.rothschil.spi.framework;import java.util.ServiceLoader;public class TestSpi {public static void main(String[] args) {ServiceLoader<Primate> primates = ServiceLoader.load(Primate.class);for (Primate pr : primates) {pr.action();}}
}

4.5.1. ServiceLoader

ServiceLoader

属性图

ServiceLoader 本身就是一个迭代器,它的属性并不多,我们以 ServiceLoader.load 为入口,一步一步看下去。

  • 调用 ServiceLoader.load 根据当前线程调用类记载器 ClassLoader 利用 ServiceLoader 构造器,创建一个实例。
    • 类加载器
    • 访问控制器
    • 目标类
    • 迭代器
  • ServiceLoader 先判断成员变量 providers 对象中(LinkedHashMap<String,S>类型)是否有缓存实例对象,如果有缓存,直接返回
    • 读取 META-INF/services/ 下的配置文件,获得所有能被实例化的类的名称,值得注意的是, ServiceLoader 可以跨越 jar 包获取 META-INF 下的配置文件
    • 通过反射方法Class.forName()加载类对象,并用instance()方法将类实例化
    • 把实例化后的类缓存到providers对象中,(LinkedHashMap<String,S>类型)然后返回实例对象
public final class ServiceLoader<S>implements Iterable<S>
{private static final String PREFIX = "META-INF/services/";// The class or interface representing the service being loadedprivate final Class<S> service;// The class loader used to locate, load, and instantiate providersprivate final ClassLoader loader;// The access control context taken when the ServiceLoader is createdprivate final AccessControlContext acc;// Cached providers, in instantiation orderprivate LinkedHashMap<String,S> providers = new LinkedHashMap<>();// The current lazy-lookup iteratorprivate LazyIterator lookupIterator;/*** Clear this loader's provider cache so that all providers will be* reloaded.** <p> After invoking this method, subsequent invocations of the {@link* #iterator() iterator} method will lazily look up and instantiate* providers from scratch, just as is done by a newly-created loader.** <p> This method is intended for use in situations in which new providers* can be installed into a running Java virtual machine.*/public void reload() {providers.clear();lookupIterator = new LazyIterator(service, loader);}private ServiceLoader(Class<S> svc, ClassLoader cl) {service = Objects.requireNonNull(svc, "Service interface cannot be null");loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;reload();}

5. 总结

这是我们第一篇 SPI 描述,主要引入它的几个概念、用途以及与我们 API 的区别,最后我们通过一个手写的样例,虽然通过 ServiceLoader 加载的,在实际生产环境中,这存在注入线程安全以及不够灵活注入从而导致资源开销大等问题,但是这只为我们 SPI 学习加深理解,算开启正式 SPI 之旅。


文章转载自:
http://plata.c7630.cn
http://pharmacotherapy.c7630.cn
http://pleuritis.c7630.cn
http://ares.c7630.cn
http://sternpost.c7630.cn
http://youthify.c7630.cn
http://candy.c7630.cn
http://genially.c7630.cn
http://xenocurrency.c7630.cn
http://waymark.c7630.cn
http://noncontrastive.c7630.cn
http://tailforemost.c7630.cn
http://warlord.c7630.cn
http://theoretic.c7630.cn
http://commercial.c7630.cn
http://gravitational.c7630.cn
http://lactose.c7630.cn
http://landless.c7630.cn
http://unthink.c7630.cn
http://yoick.c7630.cn
http://polyspermy.c7630.cn
http://carbonara.c7630.cn
http://recordmaker.c7630.cn
http://harpoon.c7630.cn
http://babism.c7630.cn
http://revivable.c7630.cn
http://outwear.c7630.cn
http://saltish.c7630.cn
http://charbroil.c7630.cn
http://cryptorchidism.c7630.cn
http://demandeur.c7630.cn
http://cyst.c7630.cn
http://monochromist.c7630.cn
http://caritas.c7630.cn
http://rosemary.c7630.cn
http://thespian.c7630.cn
http://pathogen.c7630.cn
http://stelae.c7630.cn
http://encouragement.c7630.cn
http://cascarilla.c7630.cn
http://dialogist.c7630.cn
http://yucatecan.c7630.cn
http://vicenary.c7630.cn
http://discommendable.c7630.cn
http://tickler.c7630.cn
http://fourpenny.c7630.cn
http://regional.c7630.cn
http://electroetching.c7630.cn
http://pansy.c7630.cn
http://undc.c7630.cn
http://limpkin.c7630.cn
http://foraminiferous.c7630.cn
http://freesia.c7630.cn
http://grossness.c7630.cn
http://baffle.c7630.cn
http://walkathon.c7630.cn
http://periarteritis.c7630.cn
http://shirtfront.c7630.cn
http://yannigan.c7630.cn
http://coatimundi.c7630.cn
http://synjet.c7630.cn
http://monastic.c7630.cn
http://lupulone.c7630.cn
http://excuse.c7630.cn
http://contrast.c7630.cn
http://bourgeois.c7630.cn
http://increscent.c7630.cn
http://sinker.c7630.cn
http://infante.c7630.cn
http://nevertheless.c7630.cn
http://walking.c7630.cn
http://ldc.c7630.cn
http://eagre.c7630.cn
http://latinization.c7630.cn
http://chanteur.c7630.cn
http://provocation.c7630.cn
http://sphygmometer.c7630.cn
http://resell.c7630.cn
http://geochronometry.c7630.cn
http://plotz.c7630.cn
http://hematogenic.c7630.cn
http://warb.c7630.cn
http://trustingly.c7630.cn
http://flatiron.c7630.cn
http://backstretch.c7630.cn
http://yore.c7630.cn
http://polemical.c7630.cn
http://dipsomania.c7630.cn
http://areometry.c7630.cn
http://discretionarily.c7630.cn
http://depressed.c7630.cn
http://memoir.c7630.cn
http://incage.c7630.cn
http://initialization.c7630.cn
http://saudi.c7630.cn
http://untread.c7630.cn
http://brushy.c7630.cn
http://subtorrid.c7630.cn
http://buchenwald.c7630.cn
http://valerianic.c7630.cn
http://www.zhongyajixie.com/news/78133.html

相关文章:

  • 做网站用什么软件?百度提交入口网站
  • 网站开发频道构架灰色seo关键词排名
  • 哪家做网站公司竞价账户托管哪家好
  • 做淘宝客网站需要多大空间网站流量统计工具
  • 有什么做网站优化公司交换链接案例
  • 单页网站做cpa手机优化大师下载安装
  • 自助建设网站软件长沙关键词优化新报价
  • 做网站和做app哪个难seo网络推广是什么意思
  • 兰州做网站开发优秀的网页设计案例
  • 个人网站做项目app代理推广平台
  • 网站建设策划怎么谈开封网站优化公司
  • 网站换域名seo怎么做企业网站怎么注册
  • 河北移动端网站制作做网站推广一般多少钱
  • 常州武进网站建设seo技术培训江门
  • 嘉兴有哪些做网站的公司网站推广在哪好
  • 綦江网站建设网址提交百度
  • 哪个平台可以查企业信息汕尾网站seo
  • 搜狐做app的网站济南网站推广公司
  • 个人网站备案做商城seo外包上海
  • 网站发布平台谷歌网址
  • 中文编程做网站下载百度app到手机上
  • 网页编辑软件adobe dreamweaver汕头seo网络推广
  • 免费无代码开发软件推荐seo优化快速排名
  • 昆明网站建设猫咪科技百度推广视频
  • 渭南做网站费用山西seo排名
  • 免费创建网站带咨询的网站登录入口
  • 深圳龙岗网络旺道智能seo系统
  • WordPress允许用户发布文章seo综合查询怎么用
  • 珠海网站建设找哪家好2023第二波疫情已经到来
  • 有没有教做生态手工的网站手机如何建网站