最近看到一些项目都使用SPI作为扩展机制,然后自己尝试写一下SPI的应用。
SPI的概念各种博客比较多,看看就了解了,自己就懒得写了。
SPI测试三部曲
- 定义接口
- 定义接口实现类
- 在 src/main/resources/ 下建立文件 /META-INF/services/接口名的全路劲,里面的内容就是实现类全路劲。
定义一个接口
package com.madman.inter;
/**
* <pre>
* 【类型】: Person <br/>
* 【作用】: 请填写此类的作用<br/>
* 【时间】:2018/12/18 13:55 <br/>
* 【作者】:madman <br/>
* </pre>
*/
public interface Person {
/**
* 定义吃东西的接口
*
* @param message
* @return
*/
String eat(String message);
}
定义两个实现类
**Student **
package com.madman.inter.impl;
import com.madman.inter.Person;
/**
* <pre>
* 【类型】: Student <br/>
* 【作用】: 请填写此类的作用<br/>
* 【时间】:2018/12/18 13:56 <br/>
* 【作者】:madman <br/>
* </pre>
*/
public class Student implements Person {
@Override
public String eat(String message) {
return "Student is eating " + message;
}
}
**Teacher **
package com.madman.inter.impl;
import com.madman.inter.Person;
/**
* <pre>
* 【类型】: Teacher <br/>
* 【作用】: 请填写此类的作用<br/>
* 【时间】:2018/12/18 13:57 <br/>
* 【作者】:madman <br/>
* </pre>
*/
public class Teacher implements Person {
@Override
public String eat(String message) {
return "Teacher is eating " + message;
}
}
新建META-INF.services文件夹
在resources目录下新建META-INF.services文件夹,在里面新建一个文件,文件名为com.madman.inter.Person
,然后文件内容是这样的,里面就是接口的实现类的全路劲。
com.madman.inter.impl.Student
com.madman.inter.impl.Teacher
测试类
package com.madman.test;
import com.madman.inter.Person;
import com.madman.inter.impl.Teacher;
import org.junit.Test;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* <pre>
* 【类型】: PersonTest <br/>
* 【作用】: 请填写此类的作用<br/>
* 【时间】:2018/12/18 13:58 <br/>
* 【作者】:madman <br/>
* </pre>
*/
public class PersonTest {
/**
* 测试spi
*
* @param args
*/
public static void main(String[] args) {
ServiceLoader<Person> serviceLoader = ServiceLoader.load(Person.class);
Iterator<Person> searchs = serviceLoader.iterator();
while (searchs.hasNext()) {
// System.out.println(searchs.next().getClass().getName());
System.out.println(searchs.next().eat("吃饭啦"));
}
}
//这个方法就获取到的集合就是空的,这个Teacher不是一个接口,其次是META-INF.services下面没有新建相对应的文件。
@Test
public void test01() {
ServiceLoader<Teacher> serviceLoader = ServiceLoader.load(Teacher.class);
Iterator<Teacher> searchs = serviceLoader.iterator();
while (searchs.hasNext()) {
//System.out.println(searchs.next().getClass().getName());
System.out.println(searchs.next().eat("吃饭啦"));
}
}
}
输出结果
Student is eating 吃饭啦
Teacher is eating 吃饭啦
Process finished with exit code 0
总结
尝试下来感觉最重要就是ServiceLoader<Person> serviceLoader = ServiceLoader.load(Person.class);
这句话了,待研究…