我们经常在写代码的时候用到接口,一个接口可以有不同的实现,
在spring中,可以使用注入类名或对象名来指定注入对象,
在一个大型项目中,有可能有一批接口,接口的实现封装在jar包中,我们需要将jar中的实现类,创造出来,供我们动态的使用,
这个时候,怎么能动态的,并且将这些类不耦合的创造出来呢?
java1.6之后提供了ServiceLoad类供我们使用;
简单的来说,serviceLoad给我们提供了一个通过接口名,自动查找对应实现类的功能,下边将介绍如何使用:
例子代码为:https://github.com/wentjiang/blog/tree/master/serviceLoader
我们创建一个maven项目,分为四个模块
service模块中,放入service的接口
service-one模块,实现service接口的ServiceOne类
service-two模块,实现service接口的ServiceTwo类
service-loader模块,执行main方法
在实际的开发过程中,service,提供了需要实现的接口,service-one和service-two提供了两种不同的实现方式,但是在使用的时候,只有使用的接口信息,没有service的具体实现,我们需要达到,引入jar包就能自动找到对应的类的效果,这时候,就需要用到serviceLoader类了
主类的方法:
package com.wentjiang.service.loader;
import com.wentjiang.service.Service;
import java.util.ServiceLoader;
/**
* @author wentaojiang
* @date 2019/4/7 9:31 AM
* @description
*/
public class Main {
public static void main(String[] args) {
ServiceLoader<Service> sl = ServiceLoader.load(Service.class);
for (Service service : sl){
service.doService();
System.out.println(service.serviceType());
}
}
}
service接口定义:
package com.wentjiang.service;
/**
* @author wentaojiang
* @date 2019/4/7 9:32 AM
* @description
*/
public interface Service {
void doService();
String serviceType();
}
service-one类:
package com.wentjiang.service.one;
import com.wentjiang.service.Service;
/**
* @author wentaojiang
* @date 2019/4/7 9:35 AM
* @description
*/
public class ServiceOne implements Service {
@Override
public void doService() {
System.out.println("this is service one");
}
@Override
public String serviceType() {
return "one";
}
}
service-two类:
package com.wentjiang.service.two;
import com.wentjiang.service.Service;
/**
* @author wentaojiang
* @date 2019/4/7 9:37 AM
* @description
*/
public class ServiceTwo implements Service {
@Override
public void doService() {
System.out.println("this is service two");
}
@Override
public String serviceType() {
return "two";
}
}
serviceloader如何才能找到接口对应的实现类呢?
这里需要用到java的描述文件:
在java包路径下添加对应的接口名文件,内容为该jar包所实现类的全路径
执行结果:
可以看到,执行时已经成功获得了两个不同实现方式的类;
传入Service接口,在加载的时候就能加载出所有的实现类,根据需求进行挑选就可以了,一般在编码的时候,我们只会引入一种具体的实现,
这样做的好处,实现与声明分隔开,减少代码的耦合性;