JDK SPI机制ServiceLoader源码浅析
1.load
返回创建的ServiceLoader对象
清理providers
lookupIterator指向创建的LazyIterator对象
public static <S> ServiceLoader<S> load(Class<S> service) {
// 获取当前线程的上下文类加载器
ClassLoader cl = Thread.currentThread().getContextClassLoader();
return ServiceLoader.load(service, cl);
public static <S> ServiceLoader<S> load(Class<S> service,
ClassLoader loader)
{
return new ServiceLoader<>(service, loader);
}
private ServiceLoader(Class<S> svc, ClassLoader cl) {
// ServiceLoader的字段 private final Class<S> service; private final ClassLoader loader;
service = Objects.requireNonNull(svc, "Service interface cannot be null");
loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;
// acc为null,不用关注
acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;
// 每次创建ServiceLoader对象都会清除缓存
reload();
}
public void reload() {
// private LinkedHashMap<String,S> providers = new LinkedHashMap<>();
// 清理缓存的实现类
providers.clear();
// 实例化LazyIterator
lookupIterator = new LazyIterator(service, loader);
}
private LazyIterator(Class<S> service, ClassLoader loader) {
this.service = service;
this.loader = loader;
}
2.iterator
通过iterator()获取所有的实现类
public Iterator<S> iterator() {
return new Iterator<S>() {
// 获取已有的缓存,如果有的话,会先遍历这些
Iterator<Map.Entry<String,S>> knownProviders
= providers.entrySet().iterator();
public boolean hasNext() {
if (knownProviders.hasNext())
return true;
return lookupIterator.hasNext();
}
public S next() {
if (knownProviders.hasNext())
return knownProviders.next().getValue();
return lookupIterator.next();
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
3.hasNext
是否有下一个实现类
// hasNext()调用hasNextServcie
private boolean hasNextService() {
// 如果有下一个要加载的实现类,返回ture
// String nextName是LazyIterator的字段
if (nextName != null) {
return true;
}
// LazyIterator字段 Enumeration<URL> configs = null;
if (configs == null) {
try {
// ServiceLoader的字段 private static final String PREFIX = "META-INF/services/"
// 接口名和services下的文件名一样
String fullName = PREFIX + service.getName();
if (loader == null)
configs = ClassLoader.getSystemResources(fullName);
else
// LazyIterator的字段 Enumeration<URL> configs = null;
// 获取文件资源
configs = loader.getResources(fullName);
} catch (IOException x) {
fail(service, "Error locating configuration files", x);
}
}
// LazyIterator的字段 Iterator<String> pending = null;
// 解析文件内容
while ((pending == null) || !pending.hasNext()) {
if (!configs.hasMoreElements()) {
return false;
}
pending = parse(service, configs.nextElement());
}
// 取出一个实现类
nextName = pending.next();
return true;
}
// 解析文件内容,返回实现类名List的迭代器
private Iterator<String> parse(Class<?> service, URL u)
throws ServiceConfigurationError
{
InputStream in = null;
BufferedReader r = null;
ArrayList<String> names = new ArrayList<>();
try {
in = u.openStream();
r = new BufferedReader(new InputStreamReader(in, "utf-8"));
int lc = 1;
// 一行一行解析
while ((lc = parseLine(service, u, r, lc, names)) >= 0);
} catch (IOException x) {
fail(service, "Error reading configuration file", x);
} finally {
try {
if (r != null) r.close();
if (in != null) in.close();
} catch (IOException y) {
fail(service, "Error closing configuration file", y);
}
}
return names.iterator();
}
// 解析一行,将实现类的名字加到List中,并且返回加一的lc
private int parseLine(Class<?> service, URL u, BufferedReader r, int lc,
List<String> names)
throws IOException, ServiceConfigurationError
{
String ln = r.readLine();
if (ln == null) {
return -1;
}
int ci = ln.indexOf('#');
// 截取#之前的内容并且去除前后空格
if (ci >= 0) ln = ln.substring(0, ci);
ln = ln.trim();
int n = ln.length();
if (n != 0) {
if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0))
fail(service, u, lc, "Illegal configuration-file syntax");
int cp = ln.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
fail(service, u, lc, "Illegal provider-class name: " + ln);
for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
cp = ln.codePointAt(i);
if (!Character.isJavaIdentifierPart(cp) && (cp != '.'))
fail(service, u, lc, "Illegal provider-class name: " + ln);
}
// 主要是这里,将实现类名加到List中
if (!providers.containsKey(ln) && !names.contains(ln))
names.add(ln);
}
return lc + 1;
}
4.next
加载实现类
// next()调用nextService()
public S next() {
if (acc == null) {
return nextService();
} else {
PrivilegedAction<S> action = new PrivilegedAction<S>() {
public S run() { return nextService(); }
};
return AccessController.doPrivileged(action, acc);
}
}
private S nextService() {
if (!hasNextService())
throw new NoSuchElementException();
// 获取hasNextServcie()取出的实现类
String cn = nextName;
nextName = null;
Class<?> c = null;
try {
// 加载实现类
c = Class.forName(cn, false, loader);
} catch (ClassNotFoundException x) {
fail(service,
"Provider " + cn + " not found");
}
if (!service.isAssignableFrom(c)) {
fail(service,
"Provider " + cn + " not a subtype");
}
try {
S p = service.cast(c.newInstance());
// 放到提供者列表中并返回加载的实现类
providers.put(cn, p);
return p;
} catch (Throwable x) {
fail(service,
"Provider " + cn + " could not be instantiated",
x);
}
throw new Error(); // This cannot happen
}
还没有评论,来说两句吧...