/**
* Load files under SERVICE_DIRECTORY.
*/
private void loadDirectory(final Map> classes) {
String fileName = SERVICE_DIRECTORY + clazz.getName();
try {
ClassLoader classLoader = ExtensionLoader.class.getClassLoader();
Enumeration urls = classLoader != null ? classLoader.getResources(fileName)
: ClassLoader.getSystemResources(fileName);
if (urls != null) {
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
loadResources(classes, url);
}
}
} catch (IOException t) {
log.error("load extension class error {}", fileName, t);
}
}
private void loadResources(final Map> classes, final URL url) throws IOException {
try (InputStream inputStream = url.openStream()) {
Properties properties = new Properties();
properties.load(inputStream);
properties.forEach((k, v) -> {
String name = (String) k;
String classPath = (String) v;
if (StringUtils.isNotBlank(name) && StringUtils.isNotBlank(classPath)) {
try {
loadClass(classes, name, classPath);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("load extension resources error", e);
}
}
});
} catch (IOException e) {
throw new IllegalStateException("load extension resources error", e);
}
}
private void loadClass(final Map> classes,
final String name, final String classPath) throws ClassNotFoundException {
Class> subClass = Class.forName(classPath);
if (!clazz.isAssignableFrom(subClass)) {
throw new IllegalStateException("load extension resources error," + subClass + " subtype is not of " + clazz);
}
Activate annotation = subClass.getAnnotation(Activate.class);
if (annotation == null) {
throw new IllegalStateException("load extension resources error," + subClass + " with Activate annotation");
}
Class> oldClass = classes.get(name);
if (oldClass == null) {
classes.put(name, subClass);
} else if (oldClass != subClass) {
throw new IllegalStateException("load extension resources error,Duplicate class " + clazz.getName() + " name " + name + " on " + oldClass.getName() + " or " + subClass.getName());
}
}
5、根据key,去缓存查找相应的类实例
public T getActivate(final String name) {
if (StringUtils.isBlank(name)) {
throw new NullPointerException("get Activate name is null");
}
Holder
核心代码
@Slf4j
@SuppressWarnings("all")
public final class ExtensionLoader {
private static final String SERVICE_DIRECTORY = "META-INF/services/";
private static final Map, ExtensionLoader>> LOADERS = new ConcurrentHashMap<>();
private final Class clazz;
private final Holder
使用示例
1、定义服务接口
@SPI("mysql")
public interface SqlDialect {
String dialect();
}
2、定义具体实现类
@Activate
public class MysqlDialect implements SqlDialect {
@Override
public String dialect() {
return "mysql";
}
}
@Activate
public class OracleDialect implements SqlDialect {
@Override
public String dialect() {
return "oracle";
}
}
CMS概述
并发标记清理垃圾回收(Concurrent Mark and Sweep GC)算法的主要目标是在GC过程中,减少暂停用户线程的次数以及在不得不暂停用户线程的请夸功能,尽可能短的暂停用户线程的时间。这对于交互式应用,比如web应用来说,是非常重要的。
CMS垃圾回收针对新生代和老年代采用不同的策略。相比同吞吐量垃圾回收,它要复杂的多。吞吐量垃圾回收在执
1,找到配置文件
vi /etc/sysconfig/iptables
2,添加端口开放,增加一行,开放18081端口
-A INPUT -m state --state NEW -m tcp -p tcp --dport 18081 -j ACCEPT
3,保存
ESC
:wq!
4,重启服务
service iptables
使用Android SDK Manager 更新了Anadroid SDK Tooks 之后,
打开eclipse提示 This Android SDK requires Android Developer Toolkit version 23.0.0 or above, 点击Check for Updates
检测一会后提示 No update were found