1、插件接口定义(提供插件开发者实现)
package com.zhong;
public interface PluginService {
public void service();
}
2、插件实体定义
package com.zhong;
/**
* 插件封装
* @author admin
*
*/
public class Plugin {
private String name;
private String jar;
private String className;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJar() {
return jar;
}
public void setJar(String jar) {
this.jar = jar;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
3、插件管理类
package com.zhong;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
/**
* 使用URLClassLoader动态加载jar文件,实例化插件中的对象
* @author zhong
*
*/
public class PluginManager {
private URLClassLoader urlClassLoader;
public PluginManager(List<Plugin> plugins) throws MalformedURLException {
init(plugins);
}
private void init(List<Plugin> plugins) throws MalformedURLException {
int size = plugins.size();
URL[] urls = new URL[size];
for(int i = 0; i < size; i++) {
Plugin plugin = plugins.get(i);
String filePath = plugin.getJar();
urls[i] = new URL("file:" + filePath);
}
// 将jar文件组成数组,来创建一个URLClassLoader
urlClassLoader = new URLClassLoader(urls);
}
/**
* 获得插件
* @param className
* @return
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public PluginService getInstance(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 插件实例化对象,插件都是实现PluginService接口
Class<?> clazz = urlClassLoader.loadClass(className);
Object instance = clazz.newInstance();
return (PluginService)instance;
}
}
4、读取插件配置工具类(使用dom4j实现)
package com.zhong;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 解析XML获取所有插件信息(这里用到dom4j)
* @author admin
*
*/
public class XMLParser {
public static List<Plugin> getPluginList() throws DocumentException {
List<Plugin> list = new ArrayList<Plugin>();
SAXReader saxReader =new SAXReader();
Document document = saxReader.read(new File("plugin.xml"));
Element root = document.getRootElement();
List<?> plugins = root.elements("plugin");
for(Object pluginObj : plugins) {
Element pluginEle = (Element)pluginObj;
Plugin plugin = new Plugin();
plugin.setName(pluginEle.elementText("name"));
plugin.setJar(pluginEle.elementText("jar"));
plugin.setClassName(pluginEle.elementText("class"));
list.add(plugin);
}
return list;
}
}
5、main类客户端
package com.zhong;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
List<Plugin> pluginList = XMLParser.getPluginList();
PluginManager pluginManager = new PluginManager(pluginList);
for(Plugin plugin : pluginList) {
PluginService pluginService = pluginManager.getInstance(plugin.getClassName());
System.out.println("开始执行[" + plugin.getName() + "]插件...");
// 调用插件
pluginService.service();
System.out.println("[" + plugin.getName() + "]插件执行完成");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
6、插件配置文件格式
<?xml version="1.0" encoding="UTF-8"?>
<plugins>
<plugin>
<name>A插件</name>
<jar>D:/plugins/a-plugin.jar</jar>
<class>com.zhong.aplugin.APlugin</class>
</plugin>
<plugin>
<name>B插件</name>
<jar>D:/plugins/b-plugin.jar</jar>
<class>com.zhong.bplugin.BPlugin</class>
</plugin>
<plugin>
<name>C插件</name>
<jar>D:/plugins/c-plugin.jar</jar>
<class>com.zhong.cplugin.CPlugin</class>
</plugin>
</plugins>