Many of you people would have used Service Registry concept to fetch the objects/instances of some class which provides the implementation of some service.
So that time some would be using some properties files to provide the mapping of all such classes which are providing implementations, or some would be providing these mappings as part of meta-inf folder contents of the respective jars or may be some would have used other ways.
But in short, this concept was there & was used extensively in many Enterprise Applications across the industry.
So now comes Java9 which has modularized the whole JRE itself, what a relief...
Here I will give one quick simple example to understand Service Loader in new modularized Java...
For this, we will create one Service interface module which will be used by our end Application class. Then we will create 2 other modules which provide the implentation of Service interface.
So below will be the Modules structure -
So that time some would be using some properties files to provide the mapping of all such classes which are providing implementations, or some would be providing these mappings as part of meta-inf folder contents of the respective jars or may be some would have used other ways.
But in short, this concept was there & was used extensively in many Enterprise Applications across the industry.
So now comes Java9 which has modularized the whole JRE itself, what a relief...
Here I will give one quick simple example to understand Service Loader in new modularized Java...
For this, we will create one Service interface module which will be used by our end Application class. Then we will create 2 other modules which provide the implentation of Service interface.
So below will be the Modules structure -
Now first below I am giving the content of the module-info for each module shown above-
I hope you understand the terminology used in above modules definition.
interfaceModule will be exporting the package having Service interface, so that it can be referred by other applications.
Implementation modules will not be exporting the packages having the implementation of the Service interface. Wondering why?
It is all to avoid tight coupling & have dependency only on interface. So now no application can access these implementation classes directly.
Next doubt, how the hell will I be able to use these implementation classes, if I don't have access to them?
Hmmmm....there comes provides...with part.
Note, we are using it in only those modules which are providing the implementation of Service interface & it tells the module system that this module is providing the implementation of Service interface with this particular class in this module. But not exporting the package of implementaion class to outside world for direct access.
So Service interface can be in different module but the implementation class should be in the module whose module definition is having this statement.
In short, Service interface module exports containing package & other 2 modules are just providing Service interface with their implementation & not exporting those.
Now let's see the contents of interface & classes in these modules -
interfaceModule will be exporting the package having Service interface, so that it can be referred by other applications.
Implementation modules will not be exporting the packages having the implementation of the Service interface. Wondering why?
It is all to avoid tight coupling & have dependency only on interface. So now no application can access these implementation classes directly.
Next doubt, how the hell will I be able to use these implementation classes, if I don't have access to them?
Hmmmm....there comes provides...with part.
Note, we are using it in only those modules which are providing the implementation of Service interface & it tells the module system that this module is providing the implementation of Service interface with this particular class in this module. But not exporting the package of implementaion class to outside world for direct access.
So Service interface can be in different module but the implementation class should be in the module whose module definition is having this statement.
In short, Service interface module exports containing package & other 2 modules are just providing Service interface with their implementation & not exporting those.
Now let's see the contents of interface & classes in these modules -
Will discuss later why I am using Thread.sleep() here in constructors.
First let's check the contents of Application module class & its module-info file-
First let's check the contents of Application module class & its module-info file-
Here you see 2 ways to access the instances of implementation classes.
First, module system is aware about all the modules/classes which are providing the
implementation of the given interface.
Second, Application module-info is saying that it uses this interface, note it closely that it is telling the module system that Application module is a consumer of Service Interface.
Third, Application module is telling that it uses Service Interface and requires
interfaceModule. Means module will use the interface and requires the module containing that interface.
Fourth, ServiceLoader.load(Sort.class); is loading lazy references to all the
implementation classes for the given Sort.class, as module system know which classes have registered as the provider of the implementation of this interface.
Fifth, to show this lazy instantiation, Thread.sleep(2000); is used in the implementation
classes above, so you will see that instance is not created after load(), but classes are instantiated when we call some method on those references given by load().
Sixth, you will also see that when we iterate second through the references loaded by load(), instances are created again. Here I am not sure as per some internet doc, caching of instances is possible, so when we refer again then new instance will not be created.
For sixth point above, someone can comment & let me & others know...
First, module system is aware about all the modules/classes which are providing the
implementation of the given interface.
Second, Application module-info is saying that it uses this interface, note it closely that it is telling the module system that Application module is a consumer of Service Interface.
Third, Application module is telling that it uses Service Interface and requires
interfaceModule. Means module will use the interface and requires the module containing that interface.
Fourth, ServiceLoader.load(Sort.class); is loading lazy references to all the
implementation classes for the given Sort.class, as module system know which classes have registered as the provider of the implementation of this interface.
Fifth, to show this lazy instantiation, Thread.sleep(2000); is used in the implementation
classes above, so you will see that instance is not created after load(), but classes are instantiated when we call some method on those references given by load().
Sixth, you will also see that when we iterate second through the references loaded by load(), instances are created again. Here I am not sure as per some internet doc, caching of instances is possible, so when we refer again then new instance will not be created.
For sixth point above, someone can comment & let me & others know...