背景
在研究java注解处理器的过程中,涉及到了spi机制的理解,本wiki将进行一下实践。
spi机制
spi机制的目标:实现接口与实现的解耦。
spi机制在开源项目中的应用:
- spring中大量使用(ioc的过程会自动选取一个实现)
- 数据库驱动加载
- dubbo等等
简单的理解:spi技术就是jdk提供的一种callback技术(通过ServiceLoader类),大家都按照这个规范走,jdk自然会老老实实干活
在后续的博客中将对不同的框架进行调研并加以说明。
spi简易demo
创建一个maven项目
pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mine</groupId>
<artifactId>spi-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建普通的接口和实现
DemoInterface.java
package com.mine;
public interface DemoInterface {
void myTest();
}
DemoInterfaceImpl.java
package com.mine;
public class DemoInterfaceImpl implements DemoInterface {
@Override
public void myTest() {
System.out.println("haha");
}
}
编写spi
- 添加resources/META-INF/services/com.mine.DemoInterface
- 文件内容是impl的类名:com.mine.DemoInterfaceImpl
在main中实现调用
public class Main {
public static void main(String[] args) {
ServiceLoader<DemoInterface> load = ServiceLoader.load(DemoInterface.class);
for (DemoInterface demoInterface : load) {
demoInterface.myTest();
}
}
}
运行结果如下
评价
大多开源框都运用到了spi技术,例如mapStruct
重点的好处就是:解耦合,接口定义好了,可能有多重实现,通过spi来选,能让应用层无感知