看示例以前最好先看了 classLoader和spi原理
对于spi的原理我就不多说了,网上已经有好多了。
http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html 可以参考官网。
我简单描述一个自己写的实例。
- 定义一个接口。
package com.test.spi;
public interface GetYourName {
public String getName(String name);
}
2.实现类
package com.test.spi;
public class DogName implements GetYourName {
@Override
public String getName(String name) {
if("dog".equalsIgnoreCase(name)){
return "My Name Is Dog";
}
return null;
}
}
package com.test.spi;
public class CatName implements GetYourName {
@Override
public String getName(String name) {
if("cat".equalsIgnoreCase(name)){
return "My Name Is Cat";
}
return null;
}
}
3.接口在META-INFO/services 定义
文件名称为接口名称 com.test.spi.GetYourName
文件内容为所有实现这个接口的类。一行一个
com.test.spi.CatName
com.test.spi.DogName
com.test.spi.DogName
以下为文档结构:
4、打包该spi为jar
eclipse中:选中spi工程---->右键----->export---------->java jarFile--->选中要打包的工程---->填写要存储jar的路径以及名称---->jar打包成功
5.spi使用
1、在另外一个工程里面右键---buildPath 添加外部依赖-----添加打包成功的spi.jar的依赖。
2、执行spi的测试代码
public void testSpi(){
for(GetYourName name:SpiTest.serviceLoader){
System.out.println(name.getName("cat"));;//输出名称,可以知道运行了哪个实现类
System.out.println(name.getName("dog"));
System.out.println(name.getClass()); 获取当前类名称
System.out.println(name.getClass().getClassLoader()); 当前类的classLoader 应该为appClassLoader
System.out.println(name.getClass().getClassLoader().getParent());当前类classLoader的parent 应该为 extClassloader
System.out.println(name.getClass().getClassLoader().getParent().getParent());
System.out.println("============华丽丽分割================");
}
}
运行结果: My Name Is Cat
null
class com.test.spi.CatName
sun.misc.Launcher$AppClassLoader@39ab89
sun.misc.Launcher$ExtClassLoader@2cb49d
null
============华丽丽分割================
null
My Name Is Dog
class com.test.spi.DogName
sun.misc.Launcher$AppClassLoader@39ab89
sun.misc.Launcher$ExtClassLoader@2cb49d
null
class com.test.spi.CatName
sun.misc.Launcher$AppClassLoader@39ab89
sun.misc.Launcher$ExtClassLoader@2cb49d
null
============华丽丽分割================
null
My Name Is Dog
class com.test.spi.DogName
sun.misc.Launcher$AppClassLoader@39ab89
sun.misc.Launcher$ExtClassLoader@2cb49d
null
5、classLoader使用。
public void test() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class<GetYourName> getYourName = (Class<GetYourName>) ClassLoader.getSystemClassLoader().loadClass("com.test.spi.GetYourName");
Method method1 = getYourName.getMethod("getName", String.class);
GetYourName catName = new CatName();
GetYourName dogName = new DogName();
System.out.println(method1.invoke(catName, "cat"));;
System.out.println(method1.invoke(dogName, "dog"));
}
输出结果为:My Name Is Cat
My Name Is Gog