java中的provide,Java SPI机制,Spring SPI 机制

# Java spi 机制 (Service Provider Interface) #

### 简述 ###

Service Provider Interface(SPI) 是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。

在开发过程中,将问题抽象成API,可以为API提供各种实现。如果现在需要对API提供一种新的实现,我们可以不用修改原来的代码,直接生成新的Jar包,在包里提供API的新实现。通过Java的SPI机制,可以实现了框架的动态扩展,让第三方的实现能像插件一样嵌入到系统中。

Java的SPI类似于springIOC的功能,将装配的控制权移到了程序之外,实现在模块装配的时候不用在程序中动态指明。所以SPI的核心思想就是解耦,这在模块化设计中尤其重要。

###### 简单点就是:spi是Java 内置的服务发现机制,可以被第三方扩展或实现的API, 它可以用来实现框架扩展和可替换的模块。 ######

服务调用方通过 ServiceLoader.load 加载服务接口的实现类实例

服务提供方实现服务接口后, 在自己Jar包的META-INF/services目录下新建一个接口名全名的文件, 并将具体实现类全名写入。

### Java spi 示例 ###

###### 项目结构 ######

![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70]

###### 其中 SPI-ServiceImpl-B 和 SPI-ServiceImpl-A 是一样的。 ######

创建统一的 api 接口

public interface SpiInterface {

void seyHello(String name);

}

创建接口实现

public class SpiServiceImplA implements SpiInterface {

public void seyHello(String name) {

System.out.println("AAAAAA"+name);

}

}

创建 META-INF 中的文件 注意名称路径,META-INF.services 中的文件是以,接口的全路径命名的。如上图工程中的文件一样。

文件中存放实现类的全路径: com.service.SpiServiceImplA

编写测试类:

import com.spi.SpiInterface;

import com.sun.tools.javac.util.ServiceLoader;

import java.util.Iterator;

public class application {

public static void main(String[] args) {

// 把api接口class文件传入方法中,就会自动加载所有实现

ServiceLoader load = ServiceLoader.load(SpiInterface.class);

Iterator iterator = load.iterator();

while (iterator.hasNext()){

SpiInterface spiInterface = iterator.next();

spiInterface.seyHello("hello");

}

}

}

# Spring SPI 机制 #

###### 对于Spring的SPI机制主要体现在SpringBoot中。体现在springboot四大核心之一的SpringBoot自动装配 ######

spring 中是使用 SpringFactoriesLoader类加载的:SpringFactoriesLoader.loadFactoryNames

![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70 1]

###### springboot spi 机制示例: ######

创建扩展工程

pom 文件引入 jar 包

org.springframework.boot

spring-boot-starter

2.1.6.RELEASE

true

编写具体实现类

package com.springautobean;

/** * @Author: DaoZhuang * @Date: 2020/7/15 */

public class ReidsClient {

public void seyHello(){

System.out.println("顶顶顶顶");

}

}

编写 configuration 类

package com.springautobean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/** * @Author: DaoZhuang * @Date: 2020/7/15 */

@Configuration

public class AutoBeanConfiguration {

@Bean

public ReidsClient reidsClient(){

return new ReidsClient();

}

}

在 resource 下创建 META-INF/spring.factories 文件

# key 对应springboot定义好的 org.springframework.boot.autoconfigure.EnableAutoConfiguration

# val 对应的是自己编写的 Configuration 配置类

# val 可以是多个,多个最后要加 \ 符号

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.springautobean.AutoBeanConfiguration

新建springboot 项目测试工程,在新建的项目中引入上面编写的项目 在项目中使用容器获取,实例类

@SpringBootApplication

public class SpringautobeandemoApplication {

public static void main(String[] args) {

ConfigurableApplicationContext applicationContext = SpringApplication.run(SpringautobeandemoApplication.class, args);

// 获取bean

ReidsClient reidsClient = applicationContext.getBean(ReidsClient.class);

// 打印 bean对象

System.out.println(reidsClient);

// 调用bean 方法

reidsClient.seyHello();

}

}

##### 整个工程的代码截图: #####

![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70 2]

###### 学习spi机制可以对比,springboot自动装配,dubbo spi一起学习[dubbo spi][] ######

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70]: /images/1615471477444.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70 1]: /images/1615471446486.png

[watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzg2NTMxMg_size_16_color_FFFFFF_t_70 2]: /images/1615471406305.png

[dubbo spi]: http://dubbo.apache.org/zh-cn/docs/source_code_guide/dubbo-spi.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值