1.ServiceLoader按照某种规则动态加载外部类,支持配置化方式,ClassLoader都可以加载,但有时候不如ServiceLoader方便
2.配置方式:
在META_INFO/services/接口的全路径命名的UTF-8格式的配置文件
里面的内容,具体实现类
3.可以将具体实现类和配置文件单独打成jar包
4.加载
package com.envision.energy.fe_manage.service.connector;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Map;
import java.util.ServiceLoader;
import com.envision.energy.fe_manage.share.ICollector;
public class Test2 {
private static Map<String, ICollector> map = new HashMap<String, ICollector>();
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1; i++) {
loadJar();
}
long endTime = System.currentTimeMillis();
System.out.println("耗费的时间:" + (endTime - startTime));
}
public static void loadJar() {
try {
System.getProperty("user.dir");
String jarPath = "D:\\svn\\jinlangTest_1528875616310.jar";
System.out.println(File.separator);
String path = "file:" + jarPath;//不能是"file://" 或者使用 URLurl=file.toURI().toURL();
URL url = new URL(path);
System.out.println(url);
URL urltest = new URL("file",null, jarPath);
System.out.println("urlTest="+urltest);
File file = new File(jarPath);
System.out.println(file.toURI().toURL());
ICollector collector = map.get(path);
// if (null != collector) {
// System.out.println("find");
// } else {
URLClassLoader classLoader = new URLClassLoader(new URL[] { urltest });
Class<?> loadClass = classLoader.loadClass("com.envision.energy.proto.JinLangTcp");
if (null != loadClass) {
System.out.println("find class");
ServiceLoader<ICollector> serviceLoader = ServiceLoader.load(ICollector.class, classLoader);
map.put(path, serviceLoader.iterator().next());
}
// }
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里需要注意的是,URL的构造,不能直接使用new URL("file://"+filePath),而应该使用new URL("file",null,filePath),原因如下:
1。解析格式
URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者FTP地址。
本章节我们将介绍Java是如处理URL的。URL可以分为如下几个部分。
protocol://host:port/path?query#fragment
protocol(协议)可以是 HTTP、HTTPS、FTP 和 File,port 为端口号,path为文件路径及文件名。
HTTP 协议的 URL 实例如下:
http://www.runoob.com/index.html?language=cn#j2se
URL 解析:
- 协议为(protocol):http
- 主机为(host:port):www.runoob.com
- 端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。
- 文件路径为(path):/index.html
- 请求参数(query):language=cn
- 定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。
如果你用"file://"+filePath 去构造URL,对于windows filePath是带有磁盘符的,比如:D:/xx/xx.jar,磁盘符号会被作为host,这样就会造成filePath中没有磁盘符了。这样在windows平台就没法加载了。
public static void createUrl() {
URL url;
try {
url = new URL("file://D:/home/test/file.jar");
System.out.println("URL 为:" + url.toString());
System.out.println("协议为:" + url.getProtocol());
System.out.println("验证信息:" + url.getAuthority());
System.out.println("文件名及请求参数:" + url.getFile());
System.out.println("主机名:" + url.getHost());
System.out.println("路径:" + url.getPath());
System.out.println("端口:" + url.getPort());
System.out.println("默认端口:" + url.getDefaultPort());
System.out.println("请求参数:" + url.getQuery());
System.out.println("定位位置:" + url.getRef());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}