java.util.ServiceLoader类在运行时加载服务提供者/实现。 在编译时,ServiceLoader只需要知道Service接口。 借助Java9模块化,我们可以在运行时动态添加服务实现模块,而Application可以拥有新的实现,而不会影响任何事情,
让我们以示例进行检查,并使用EventService.java接口创建模块EventsAPI
EventsAPI / EventService.java
package events.api;public interface EventService {public String getName();
}
EventsAPI /模块信息.java
module events.api {exports events.api;
}
在另一个名为FacebookEvents的模块中为EventService接口创建一个实现
FacebookEvents / FacebookEventService.java
package events.api.facebook;
import events.api.EventService;public class FacebookEventService implements EventService{public FacebookEventService() {System.out.println("FacebookEventService Constructor");}public String getName() {return "facebook events";}
}
FacebookEvents / module-info.java
module events.api.facebook {requires events.api;provides events.api.EventServicewith events.api.facebook.FacebookEventService;
}
FacebookEvents模块需要EventsAPI,因为它需要有权访问EventService.java接口。
并且它通过 FacebookEventService 提供 EventService实现。
让我们创建一个客户端模块EventsClient以使用EventsAPI
EventsClient / module-info.java
module client.calendar {
requires events.api;
uses events.api.EventService;
}
我们将使用ServiceLoader查找EventService接口的实现,此处ServiceLoader需要在EventService上使用uses关键字,否则编译器将引发错误。
最终客户测试课程
EventsClient / Calendar.java
package client.calendar;
import java.util.ServiceLoader;
import events.api.EventService;public class Calendar {
public static void main(String[] args) {
System.out.println("Calendar events..!!!");
ServiceLoader<EventService> events = ServiceLoader.load(EventService.class);for(EventService event : events) {
System.out.println(event.hashCode() + " : " +event.getName());
}
events.reload();
for(EventService event : events) {
System.out.println(event.hashCode() + " : " +event.getName());
}
}
}
在EventsClient模块中,我们没有提及任何有关FacebookEvents模块的信息,而在运行上述Calendar.java add FacebookEvents模块时,输出为
输出
Calendar events..!!!
FacebookEventService Constructor
1627960023 : facebook events
FacebookEventService Constructor
745160567 : facebook events
ServiceLoader找到了EventService实现FacebookEventService并显示了输出,让我们向EventService接口添加另一个实现并检查上述客户端的输出
TwitterEvents / module-info.java
module events.api.twitter {
requires events.api;
provides events.api.EventService
with events.api.twitter.TwitterEventService;
}
与FacebookEventService相同,将具有TwitterEventService,它将实现EventService接口
TwitterEvents / TwitterEventService.java
package events.api.twitter;import events.api.EventService;public class TwitterEventService implements EventService{public TwitterEventService() {
System.out.println("TwitterEventService Constructor");
}public String getName() {
return "twitter events";
}
}
通过在模块路径上添加TwitterEvents模块来运行EventsClient / Calendar.java ,输出如下
日历活动.. !!!
TwitterEventService Constructor
249515771 : twitter events
FacebookEventService Constructor
1627960023 : facebook events
TwitterEventService Constructor
321142942 : twitter events
FacebookEventService Constructor
745160567 : facebook events
我们刚刚在运行时添加了TwitterEvents模块,ServiceLoader能够加载TwitterEventService并提供所需的输出。
源代码位于https://github.com/rameshcharykotha/java9practice
谢谢阅读..!!
翻译自: https://www.javacodegeeks.com/2017/10/java-9-serviceloader.html