详谈详谈ServiceLoader实现原理实现原理
下面小编就为大家带来一篇详谈ServiceLoader实现原理。小编觉得挺不错的,现在就分享给大家,也给大家做
个参考。一起跟随小编过来看看吧
在java中根据一个子类获取其父类或接口信息非常方便,但是根据一个接口获取该接口的所有实现类却没那么容易。
有一种比较笨的办法就是扫描classpath所有的class与jar包中的class,然后用ClassLoader加载进来,然后再判断是否是给定
接口的子类。但是很显然,不会使用这种方法,代价太大。
java本身也提供了一种方式来获取一个接口的子类,那就是使用java.util.ServiceLoader#load(java.lang.Class<S>) 方法,但是
直接使用该方法也是不能获取到给定接口所有的子类的。
需要接口的子类以配置的方式主动注册到一个接口上,才能使用ServiceLoader进行加载到子类,并且子类需要有一个无参构
造方法,用于被ServiceLoader进行实例化
下面介绍使用下面介绍使用ServiceLoader的步骤的步骤
1、、 编写编写Service
package com.mogujie.uni.sl;
/**
* Created by laibao
*/
public interface Animal {
void eat();
}
2、编写实现类(注意:实现类不一定要与接口在同一个工程中,可以存在于其他的、编写实现类(注意:实现类不一定要与接口在同一个工程中,可以存在于其他的jar包中)包中)
package com.mogujie.uni.sl;
/**
* Created by laibao
*/
public class Pig implements Animal {
@Override
public void eat() {
System.out.println("Pig eating...");
}
}
package com.mogujie.uni.sl;
/**
* Created by laibao
*/
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog eating...");
}
}
3、、 在实现类所在的工程的在实现类所在的工程的classpath下面的建立下面的建立META-INF/services目录,该目录是固定的,一定要按照规定的名称去创目录,该目录是固定的,一定要按照规定的名称去创
建,该目录用于配置接口与实现类的映射关系建,该目录用于配置接口与实现类的映射关系
然后根据接口全名 在该目录创建一个文件,例如上面例子中接口全名是com.mogujie.uni.sl.Animal,那么就需要在实现类的工
程中建立META-INF/services/com.mogujie.uni.sl.Animal这样一个文件,然后在该文件中配置该接口的实现类,如果该接口有
多个实现类,一行写一个(以换行符分割),例如:
com.mogujie.uni.sl.Pig
com.mogujie.uni.sl.Dog
4、接下来就能使用、接下来就能使用ServiceLoader的方法获取的方法获取com.mogujie.uni.sl.Animal接口的所有子类了。接口的所有子类了。
测试类如下:测试类如下:
package com.mogujie.uni;
import com.mogujie.uni.sl.Animal;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* Created by laibao
*/
评论0
最新资源