当前位置:网站首页>SPI mechanism
SPI mechanism
2022-07-03 02:09:00 【xixingzhe2】
1、 Concept
spi Its full name is (Service Provider Interface), yes JDK A built-in service discovery mechanism .SPI It's a dynamic replacement discovery mechanism , An excellent idea of decoupling . It is jdk Provide to “ Service provider ” perhaps “ Plug in developers ” Interface used , It's an extension mechanism .
2、 purpose
In object-oriented design , We usually adopt interface oriented programming between modules , In the actual programming process ,API The implementation of is encapsulated in jar in , When we want to change the implementation method , Also generate new jar Replace the previous implementation class . And by jdk Of SPI Mechanism can be realized , First of all, there is no need to modify the original interface jar Under the circumstances , The original implementation jar Replace with another implementation jar that will do .
To sum up SPI Thought : In each module of the system , There are often different implementation schemes , For example, the scheme of the log module 、xml Analytical scheme, etc , In order not to specify the implementation class when loading the module , We need a service discovery mechanism ,java spi Provide such a mechanism . It's kind of like IoC Thought , Move control of the service assembly out of the program , Especially important in modular design .
Example : Rewrite third party jar in SPRING BEAN The way _xixingzhe2 The blog of -CSDN Blog
3、 Advantages and disadvantages
3.1 advantage
- To decouple , Separate the interface from the implementation .
- Improve the extensibility of the framework . The application can enable framework extension or replace framework components according to the actual business situation , Avoid writing interfaces and implementations together , The caller has no right to choose to use specific implementation classes .
3.2 shortcoming
- although ServiceLoader It's also the delay load used , But basically only through traversal all get , That is to say, all the implementation classes of the interface are loaded and instantiated once . If you don't want to use some implementation classes , It's also loaded and instantiated , This creates waste . The way to get an implementation class is not flexible enough , Only through Iterator Form acquisition , The corresponding implementation class cannot be obtained according to a certain parameter .
- Multiple concurrent multithreading use ServiceLoader An instance of a class is not safe .
4、 standard
Define the common interface of the service , For common service interfaces , Provide specific implementation classes .
- stay jar package ( Service providers ) Of META-INF/services/ Directory , Create a new file , The file named SPI Interface " All names are limited "( Such as :com.ybw.spi.service.DemoService). The content of the file is the specific implementation class of the interface " All names are limited "( Such as :com.ybw.spi.service.impl.DemoOneServiceImpl).
- take spi Where jar In the main program classpath in .
- The service caller uses java.util.ServiceLoader To dynamically load specific implementation classes to JVM in .
5、SPI Example
The code structure
Module dependencies
5.1 spi-service
Defining interfaces
package com.ybw.spi.service;
/**
* Demo service. Implements should be use SPI.
*
* @author ybw
* @version V1.0
* @className DemoService
* @date 2022/6/29
**/
public interface DemoService {
String sayHello();
}
5.2 spi-service-impl-one
Achieve one
package com.ybw.spi.service.impl;
import com.ybw.spi.service.DemoService;
/**
* Implement for DemoService
*
* @author ybw
* @version V1.0
* @className DemoOneServiceImpl
* @date 2022/6/29
**/
public class DemoOneServiceImpl implements DemoService {
@Override
public String sayHello() {
return "hello world one";
}
}
META-INF/services/ Create a file com.ybw.spi.service.DemoService, The content is
com.ybw.spi.service.impl.DemoOneServiceImpl
5.3 spi-service-impl-two
Achieve two
package com.ybw.spi.service.impl;
import com.ybw.spi.service.DemoService;
/**
* Implement for DemoService
*
* @author ybw
* @version V1.0
* @className DemoOneServiceImpl
* @date 2022/6/29
**/
public class DemoTwoServiceImpl implements DemoService {
@Override
public String sayHello() {
return "hello world two";
}
}
META-INF/services/ Create a file com.ybw.spi.service.DemoService, The content is
com.ybw.spi.service.impl.DemoTwoServiceImpl
5.4 spi-execute
Perform module
package com.ybw.spi.test;
import com.ybw.spi.service.DemoService;
import com.ybw.spi.service.impl.DemoOneServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.util.ServiceLoader;
/**
* Load using
*
* @author ybw
* @version V1.0
* @className SpiTest
* @date 2022/6/29
**/
@Slf4j
public class SpiTest {
/**
* @methodName: spiTest
* @return: void
* @author: ybw
* @date: 2022/6/29
**/
@Test
public void spiTest() {
ServiceLoader<DemoService> demoServices = ServiceLoader.load(DemoService.class);
demoServices.forEach(demoService -> {
log.info(demoService.getClass().getName());
log.info("ClassLoader:{}",demoService.getClass().getClassLoader());
log.info(demoService.sayHello());
});
}
}
Introduce dependencies spi-service-impl-one
Input log
[INFO ] 2022-06-29 16:12:58.135 [main] com.ybw.spi.test.SpiTest - com.ybw.spi.service.impl.DemoOneServiceImpl
[INFO ] 2022-06-29 16:12:58.146 [main] com.ybw.spi.test.SpiTest - ClassLoader:[email protected]
[INFO ] 2022-06-29 16:12:58.151 [main] com.ybw.spi.test.SpiTest - hello world one
The implementation modules introduced are different , The printed log will also be different .
5.5 Code address
https://gitee.com/xixingzhe2/share/tree/master/spi/spi-jdk-demo
6、spring spi
stay springboot In the process of automatic assembly , It will eventually load META-INF/spring.factories file , And the loading process is made up of SpringFactoriesLoader Loaded .
from CLASSPATH Each of the following Jar Search the bag for all META-INF/spring.factories The configuration file , Then it will parse properties file , Find the configuration with the specified name and return . Pay attention to is , In fact, it's not just going to ClassPath Find... In the path , It will scan all paths Jar package , It's just that this file will only be in Classpath Under the jar In bag .
You can read the article on the other side :spring boot Customize starter_xixingzhe2 The blog of -CSDN Blog
Source code :https://gitee.com/xixingzhe2/share/tree/master/spring/spring-demo-starter-parent
7、jdk And spring spi difference
jdk | spring | |
Different loading classes | JDK The tool class used is ServiceLoader | Spring The class used in is SpringFactoriesLoader, stay org.springframework.core.io.support In bag |
The file path is different | jdk The configuration is in META-INF/services/ Directory | spring The configuration is in META-INF/spring.factories in |
边栏推荐
- 可视化yolov5格式数据集(labelme json文件)
- Depth (penetration) selector:: v-deep/deep/ and > > >
- 使用Go语言实现try{}catch{}finally
- udp接收队列以及多次初始化的测试
- Analysis, use and extension of open source API gateway apisex
- [Flutter] dart: class;abstract class;factory;类、抽象类、工厂构造函数
- Method of removing webpage scroll bar and inner and outer margins
- Wechat applet Development Tool Post net:: Err Proxy Connexion Problèmes d'agent défectueux
- DML Foundation
- MySQL learning 03
猜你喜欢
详细些介绍如何通过MQTT协议和华为云物联网进行通信
Solution for processing overtime orders (Overtime unpaid)
udp接收队列以及多次初始化的测试
Redis: simple use of redis
[camera topic] how to save OTP data in user-defined nodes
Detailed introduction to the usage of Nacos configuration center
stm32F407-------DMA
elastic stack
【Camera专题】OTP数据如何保存在自定义节点中
What are MySQL locks and classifications
随机推荐
机器学习笔记(持续更新中。。。)
Iptables layer 4 forwarding
Prohibited package name
Explore the conversion between PX pixels and Pt pounds, mm and MM
His experience in choosing a startup company or a big Internet company may give you some inspiration
File class (check)
require.context
elastic stack
[shutter] shutter debugging (debugging fallback function | debug method of viewing variables in debugging | console information)
Unrecognized SSL message, plaintext connection?
In the face of difficult SQL requirements, HQL is not afraid
Analysis, use and extension of open source API gateway apisex
Kotlin middle process understanding and Practice (II)
[shutter] pull the navigation bar sideways (drawer component | pageview component)
苏世民:25条工作和生活原则
缺少库while loading shared libraries: libisl.so.15: cannot open shared object file: No such file
Reprint some Qt development experience written by great Xia 6.5
Network security - Trojan horse
Stm32f407 ------- IIC communication protocol
Startup mode and scope builder of collaboration in kotlin