1. Mito
2. Overview
ServiceLoader and Java ClassLoader is the difference between the two and that is mutually interrelated loader .JVM use ClassLoader class will be loaded into memory, this is the first step in a class declaration period (a java class of complete lifecycle experience loaded, connection, initialization, use, and unloaded five stages, of course, there are circumstances after the connection has not been initialized or loaded directly be used).
That ServiceLoader what is it?
ServiceLoader: a simple service provider loading facilities. It is a well-known service interfaces and classes (typically abstract class) set. Service provider is a specific implementation of a service. Providers typically implement the interface classes, subclasses and subclasses defined in the service itself. Service providers can be installed to extend in the form of implementation of the Java platform, that is, jar files into any of the usual extensions directory. It may also be added by the application class path provider, or made in some other way by a particular platform available. ...... The only requirement is mandatory, the provider must have a class constructor with no arguments, so that they can be instantiated during loading.
By resource directory META-INF/services
provider configuration file to identify the service provider is placed in. File names are service type of fully qualified binary name. The binary file contains a list of specific provider class fully qualified names, one per line. Ignore surrounding each name spaces, tabs, and blank lines. The comment character is '#'('\u0023', NUMBER SIGN)
; ignore all characters following the first comment of characters per line. The file must use UTF-8 encoding.
To 延迟方式查找和实例化提供者
, that is to say as needed. Loader maintenance service provider caches so far has been loaded. Each call returns an iterator iterator method, it first generates all the elements of the cache according to Example sequence, then find and instantiate any remaining providers in a delayed manner, adding each one to the cache. You can clear the cache by reload method.
ServiceLoader, like ClassLoader same class file can be loaded, but there are differences when using specific differences are as follows:
- It is a series of loading ServiceLoader
某种共同特征
implementation class, while a universal ClassLoader loader; - Require special configuration when loading ServiceLoader, also differ ClassLoader use;
- ServiceLoader also implements the Iterator interface.
3. Case
Basic services: IService
package com.service;
public interface IService {
String sayHello();
String getScheme();
}
Specific services implementation, here deliberately wrote two
package com.impl;
import com.service.IService;
public class HDFSService implements IService {
@Override
public String sayHello() {
return "Hello HDFSService";
}
@Override
public String getScheme() {
return "hdfs";
}
}
package com.impl;
import com.service.IService;
public class LocalService implements IService {
@Override
public String sayHello() {
return "Hello LocalService";
}
@Override
public String getScheme() {
return "local";
}
}
配置:META-INF/services/com.service.IService
com.impl.HDFSService
com.impl.LocalService
Test category
package com.test;
import java.util.ServiceLoader;
import com.service.IService;
public class Test {
public static void main(String[] args) {
ServiceLoader<IService> serviceLoader = ServiceLoader.load(IService.class);
for(IService service : serviceLoader) {
System.out.println(service.getScheme()+"="+service.sayHello());
}
}
}
result:
hdfs=Hello HDFSService
local=Hello LocalService
ServiceLoader can be seen to define two classes implement according IService find out, to achieve a return of ServiceLoader, and ServiceLoader achieve the Iterable interface, it is possible to traverse all the instances defined in the configuration file by ServiceLoader class.
4.ServiceLoader applications
4.1 Hadoop FileSystem
Hadoop FileSystem is through this mechanism to return to a different FileSystem scheme according to different files.
private static void loadFileSystems() {
synchronized(FileSystem.class){
if(!FILE_SYSTEMS_LOADED) {
ServiceLoader<FileSystem> serviceLoader = ServiceLoader.load(FileSystem.class);
for(FileSystem fs : serviceLoader) {
SERVICE_FILE_SYSTEMS.put(fs.getScheme(),fs.getClass());
}
FILE_SYSTEMS_LOADED= true;
}
}
}
The corresponding configuration file:
org.apache.hadoop.fs.LocalFileSystem
org.apache.hadoop.fs.viewfs.ViewFileSystem
org.apache.hadoop.fs.s3.S3FileSystem
org.apache.hadoop.fs.s3native.NativeS3FileSystem
org.apache.hadoop.fs.kfs.KosmosFileSystem
org.apache.hadoop.fs.ftp.FTPFileSystem
org.apache.hadoop.fs.HarFileSystem
By testing before the output corresponding to the class and class scheme as follows:
file=class org.apache.hadoop.fs.LocalFileSystem
viewfs=class org.apache.hadoop.fs.viewfs.ViewFileSystem
s3=class org.apache.hadoop.fs.s3.S3FileSystem
s3n=class org.apache.hadoop.fs.s3native.NativeS3FileSystem
kfs=class org.apache.hadoop.fs.kfs.KosmosFileSystem
ftp=class org.apache.hadoop.fs.ftp.FTPFileSystem
har=class org.apache.hadoop.fs.HarFileSystem
hdfs=class org.apache.hadoop.hdfs.DistributedFileSystem
hftp=class org.apache.hadoop.hdfs.HftpFileSystem
hsftp=class org.apache.hadoop.hdfs.HsftpFileSystem
webhdfs=class org.apache.hadoop.hdfs.web.WebHdfsFileSystem
It can be seen that all implementations will have to the FileSystem FileSystem class scheme and to cache, then to take the appropriate value from the cache. Therefore, in the future it can be achieved through some similar features ServiceLoader, without relying on third-party frameworks such as Spring.
4.2 sprak achieve
4.3 spring boot
spring boot, there are many places are using a similar configuration, or is used in this way.
Reference: the Spring: What is this Factories exists
4.3.1 SpringBoot Starters starter
Starters can be understood as a starter, which contains a series of applications which can be integrated into dependencies, no matter what frame you want to use technology, a lead starter
can be a good make Spring
and other framework integration, no additional integration work . If you want to use Spring JPA
to access the database, just add spring-boot-starter-data-jpa
starter depend ready to use.
Spring is how the design of starter
There are many surrounding blog describes how to customize the starter, you will need to add a configuration file spring.factories in the META-INF directory of resources in the last step
SpringBoot startup scans all the resource files spring.factories jar package introduced, the reading of which AutoConfiguration autoconfiguration class starter spring to register class management container.
The mechanism is based on the idea of SPI, its core class SpringFactoriesLoader with similar ServiceLoader
4.4 SPI
spi is the principle.
ServiceLoader is an implementation of SPI, a so-called SPI, i.e. Service Provider Interface, used to achieve some of the services provided to the third party or extended, can be extended to enhance or replace some components of the frame.
SPI after the full name of Service Provider Interface, as service providers, provides an implementation of the service interface, service interface to simultaneously create a file named META-INF jar package / services / directory. The document is the realization of the service implementation class interface. And when the external program module assembly, to find a specific category by the name of the jar package META-INF / services / in the configuration file loading instantiates and complete injection module.
4.5 common-logging
the first to provide facade apache log interface. Only the interface has not been achieved. Specific programs to achieve by the provider, log provider is found by scanning META-INF/services/org.apache.commons.logging.LogFactory
the configuration file, by reading the contents of the log file to find mention industrial and commercial implementation class. As long as we realize the log contains the file, and to develop in the file LogFactory
class that implements the interface to the plant.
4.6 SLF4J
Logging framework SLF4J chose this path. SLF4J itself API, but may use different implementations (e.g. Logback, Log4J, etc.), SLF4J client only interact with SLF4J the API abstract interface module, it is possible in a different manner is placed on the classpath different implementation module at runtime details of the deal.
4.7 jdbc
jdbc4.0 Previously, developers also need to be based Class.forName("xxx")
ways to load the driver, jdbc4 also spi-based mechanism to find the driver provider, you can META-INF/services/java.sql.Driver
specify the implementation class to expose driven provider file.