当前位置:网站首页>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 |
边栏推荐
- A 30-year-old software tester, who has been unemployed for 4 months, is confused and doesn't know what to do?
- LabVIEW安装第三方VISA软件后NI VISA失效
- Internal connection query and external connection
- Y54. Chapter III kubernetes from introduction to mastery -- ingress (27)
- Socket编程
- [fluent] hero animation (hero animation use process | create hero animation core components | create source page | create destination page | page Jump)
- iptables 4层转发
- Kotlin middle process understanding and Practice (II)
- 【Camera专题】OTP数据如何保存在自定义节点中
- 详细些介绍如何通过MQTT协议和华为云物联网进行通信
猜你喜欢
What are MySQL locks and classifications
全链路数字化转型下,零售企业如何打开第二增长曲线
Rockchip3399 start auto load driver
Certaines fonctionnalités du développement d'applets
深度学习笔记(持续更新中。。。)
[fluent] fluent debugging (debug debugging window | viewing mobile phone log information | setting normal breakpoints | setting expression breakpoints)
詳細些介紹如何通過MQTT協議和華為雲物聯網進行通信
微信小程序開發工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理問題
机器学习笔记(持续更新中。。。)
Wechat applet development tool post net:: err_ PROXY_ CONNECTION_ Failed agent problem
随机推荐
DDL basic operation
stm32F407-------DMA
Job object of collaboration in kotlin
Learn BeanShell before you dare to say you know JMeter
去除网页滚动条方法以及内外边距
Return the only different value (de duplication)
[shutter] shutter debugging (debugging fallback function | debug method of viewing variables in debugging | console information)
Rockchip3399 start auto load driver
转载收录6.5大侠写的部分Qt开发经验
Anna: Beibei, can you draw?
Unrecognized SSL message, plaintext connection?
创建+注册 子应用_定义路由,全局路由与子路由
iptables 4层转发
[shutter] bottom navigation bar implementation (bottomnavigationbar bottom navigation bar | bottomnavigationbaritem navigation bar entry | pageview)
树形结构数据的处理
详细些介绍如何通过MQTT协议和华为云物联网进行通信
2022 spring "golden three silver four" job hopping prerequisites: Software Test interview questions (with answers)
Groovy, "try with resources" construction alternative
Wechat applet Development Tool Post net:: Err Proxy Connexion Problèmes d'agent défectueux
elastic stack