当前位置:网站首页>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 |
边栏推荐
- Summary of ES6 filter() array filtering methods
- [camera topic] complete analysis of camera dtsi
- Cancellation of collaboration in kotlin, side effects of cancellation and overtime tasks
- Prohibited package name
- [fluent] fluent debugging (debug debugging window | viewing mobile phone log information | setting normal breakpoints | setting expression breakpoints)
- 502 (bad gateway) causes and Solutions
- 微服务组件Sentinel (Hystrix)详细分析
- 【Camera专题】Camera dtsi 完全解析
- Network security - scan
- How do browsers render pages?
猜你喜欢
Comment communiquer avec Huawei Cloud IOT via le Protocole mqtt
使用Go语言实现try{}catch{}finally
Job object of collaboration in kotlin
[camera topic] how to save OTP data in user-defined nodes
How can retail enterprises open the second growth curve under the full link digital transformation
elastic stack
[shutter] hero animation (hero realizes radial animation | hero component createrecttween setting)
PyTorch 卷积网络正则化 DropBlock
In the face of difficult SQL requirements, HQL is not afraid
Wechat applet development tool post net:: err_ PROXY_ CONNECTION_ Failed agent problem
随机推荐
Technology sharing | Frida's powerful ability to realize hook functions
[camera topic] complete analysis of camera dtsi
我的创作纪念日
各国Web3现状与未来
The Sandbox阐释对元宇宙平台的愿景
深度(穿透)选择器 ::v-deep/deep/及 > > >
树形结构数据的处理
udp接收队列以及多次初始化的测试
Startup mode and scope builder of collaboration in kotlin
String replace space
可視化yolov5格式數據集(labelme json文件)
Detailed introduction to the deployment and usage of the Nacos registry
机器学习流程与方法
Redis: simple use of redis
How do it students find short-term internships? Which is better, short-term internship or long-term internship?
Where is the future of test engineers? Confused to see
PyTorch 卷积网络正则化 DropBlock
[Flutter] dart: class;abstract class;factory;类、抽象类、工厂构造函数
MySQL学习03
[leetcode] 797 and 1189 (basis of graph theory)