Java 9: ServiceLoader
java.util.ServiceLoader class loads the service providers/implementations at run time. While compile time ServiceLoader just need to know Service interface. With the Java9 modularity, we can add service implementation modules dynamically at run time, And Application can have new implementation with out effecting anything,
lets check with an example, create a module EventsAPI with an interface EventService.java
EventsAPI/EventService.java
package events.api; public interface EventService { public String getName(); }
EventsAPI/module-info.java
module events.api { exports events.api; }
Create an implementation to the EventService interface in another module called FacebookEvents
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.EventService with events.api.facebook.FacebookEventService; }
FacebookEvents module requires EventsAPI, because it need to have access to EventService.java interface.
And it provides EventService implementation with FacebookEventService.
Lets create a Client module EventsClient to consume EventsAPI
EventsClient/module-info.java
module client.calendar { requires events.api; uses events.api.EventService; }
We are going to use ServiceLoader to find the implementations of EventService interface, here ServiceLoader requires uses keyword on EventService, otherwise compiler will throw an error.
Finally Client Test class
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()); } } }
In the EventsClient module, we din’t mention anything about FacebookEvents module, while running the above Calendar.java add FacebookEvents module, the output will be
output
Calendar events..!!! FacebookEventService Constructor 1627960023 : facebook events FacebookEventService Constructor 745160567 : facebook events
ServiceLoader found the EventService implementation FacebookEventService and showed the output, lets add another implementation to the EventService interface and examine the output from above client
TwitterEvents/module-info.java
module events.api.twitter { requires events.api; provides events.api.EventService with events.api.twitter.TwitterEventService; }
same as FacebookEventService, will have TwitterEventService which will implement EventService interface
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"; } }
Run the EventsClient/Calendar.java by adding TwitterEvents module on the modulepath, output as follows
Calendar events..!!!
TwitterEventService Constructor 249515771 : twitter events FacebookEventService Constructor 1627960023 : facebook events TwitterEventService Constructor 321142942 : twitter events FacebookEventService Constructor 745160567 : facebook events
We have just added TwitterEvents module in the run time, ServiceLoader is able to load the TwitterEventService and gave the desired output.
Source code is available at https://github.com/rameshcharykotha/java9practice
Thanks for reading..!!
Published on Java Code Geeks with permission by Ramesh Kotha, partner at our JCG program. See the original article here: Java9 : ServiceLoader Opinions expressed by Java Code Geeks contributors are their own. |