String Apath = "D:/work/ModelA/bin/"; 一定加“/” String Bpath = "D:/work/ModelB/bin/"; URL aurl = new URL("file", "", -1, Apath); URL burl = new URL("file", "", -1, Bpath); URLClassLoader Aloader =new URLClassLoader(new URL[]{aurl}); URLClassLoader Bloader =new URLClassLoader(new URL[]{burl}); PluginCenter center =PluginCenter.getInstance(); center.putClassLoader("A", Aloader); center.putClassLoader("B", Bloader); IActivator i1 = (IActivator)Aloader.loadClass("com.a.AActivator").newInstance(); IActivator i2 = (IActivator)Bloader.loadClass("com.b.BActivator").newInstance();; System.out.println(i1.getClass().getClassLoader()); System.out.println(i2.getClass().getClassLoader()); i1.init(); i2.init(); center.dispathNotice("A"); System.out.println(Inint.class.getClassLoader().getClass().getName()); System.out.println(Aloader.getParent().getClass().getName());
Aloader Bloader的父加载器是本类的加载器,所以A,B模块可以直接引用本模块的类
public class Application { private Logger logger = LoggerManager.getLogger(Application.class); private final LinkedHashSet<IApplicationListener> listeners = new LinkedHashSet<IApplicationListener>(); private final LinkedHashSet<IApplicationModule> modules = new LinkedHashSet<IApplicationModule>(); private ApplicationContext context; private ApplicationControl control; // 默认内置模块 { install(Runtime.getRuntime().LISTENER); install(new DataCenterModule()); } /** * 安装容器监听器,相同的监听器实例只会被安装一次,注意,listener 不能为NULL。 * * @param listener * 监听器实例 */ protected void install(IApplicationListener listener) { listeners.add(listener); } /** * 安装模块,相同的模块只会被安装一次,注意,module不能为 NULL。 * * @param module */ protected void install(IApplicationModule module) { modules.add(module); } /** * 启动运行容器。 */ public void startup() { logger.info("x Application starting..."); try { createApplicationContext(); initialize(); // 初始化启动环境 // fire before startup fireEvent(EventType.BEFORE_STARTUP); // fire startup fireEvent(EventType.STARTUP); // fire after startup fireEvent(EventType.AFTER_STARTUP); } catch (Exception e) { throw new RuntimeException(e); } logger.info(" Application start success"); System.out.println("服务已启动"); Thread shutdownHook = new Thread() { public void run() { shutdown(); } }; java.lang.Runtime.getRuntime().addShutdownHook(shutdownHook); synchronized (this) { while (Runtime.getRuntime().getApplicationStatus() != Status.STOPPED) { try { wait(); } catch (InterruptedException e) {} } } System.exit(0); } /** * 关闭运行容器。 */ public void shutdown() { final Status status = Runtime.getRuntime().getApplicationStatus(); if (status != Status.RUNNING && status != Status.STARTING) { logger.info(" Application isn't started"); return; } logger.info("Application stopping..."); try { // fire before shutdown fireEvent(EventType.BEFORE_SHUTDOWN); // fire shutdown // logger.info("Application is stopping"); fireEvent(EventType.SHUTDOWN); // fire after shutdown // logger.info("Application is stopped"); fireEvent(EventType.AFTER_SHUTDOWN); } catch (Exception e) { throw new RuntimeException(e); } logger.info("Application stop success"); System.out.println("服务已停止"); synchronized (this) { this.notify(); } } public ApplicationContext getApplicationContext() { return context; } /** * 获取模块实例,指定参数为该模块的实现类,如果对应的模块不 存在或没有注册,则返回NULL。 * * @param <T> * 模块实现类泛型 * @param module * 指定模块的实现类 * @return 模块实例,如果不存在或没有注册,返回NULL。 */ public <T extends IApplicationModule> T getModule(Class<T> module) { for (IApplicationModule m : modules) { if (m.getClass() == module) { return (T) m; } } return null; } /** * Application运行容器统一事件分发,根据EventType的类型分阶段分发事件, * 事件分发顺序如下,分二阶段(启动、关闭),其中前置和后置事件由listener 负责处理,启动、关闭事件由module处理: * * 1. 启动 BEFORE_STARTUP STARTUP AFTER_STARTUP * * 2. 关闭 BEFORE_SHUTDOWN SHUTDOWN AFTER_SHUTDOWN * * @param type * EventType事件类型 */ private void fireEvent(EventType type) throws Exception { ApplicationEvent event = new ApplicationEvent(type, context); // fire "before event" to all listeners for (IApplicationListener listener : listeners) { switch (type) { case BEFORE_STARTUP: listener.beforeStartup(event); break; case BEFORE_SHUTDOWN: listener.beforeShutdown(event); break; } } // do fire MODULES for (IApplicationModule module : modules) { switch (type) { case STARTUP: module.startup(event); break; case SHUTDOWN: module.shutdown(event); break; } } // fire "after event" to all listeners for (IApplicationListener listener : listeners) { switch (type) { case AFTER_STARTUP: listener.afterStartup(event); break; case AFTER_SHUTDOWN: listener.afterShutdown(event); break; } } } /** * 初始化运行容器,动态加载外挂模块 * * @throws Exception */ protected void initialize() { // do nothing control = new ApplicationControl(this); DataCenterConfig.load(); // 加载配置 } public IApplicationControl getApplicationControl() { return control; } /** * 创建上下文信息。 */ protected void createApplicationContext() { if (context != null) { return; } context = new ApplicationContext(this); Runtime.getRuntime().setApplication(this); Runtime.getRuntime().setApplicationContext(context); } public static void main(String[] args) { Application application = new Application(); application.startup(); } }
从配置文件实例化模型
lServiceLauncher launcher = new ServiceLauncher();public abstract class Service implements IService { protected Logger logger = LoggerManager.getLogger(getClass()); private ServiceConfig config; // 三个阶段 private final int inited = 0; private final int started = 1; private final int stopped = 2; private int state = stopped; public void setState(int state) { this.state = state; } private int getState() { return state; } public void init() { try { if (!isInited()) { logger.info(String.format("service[%s] initializing", getName())); initService(); logger.info(String.format("service[%s] initialized", getName())); setState(inited); } } catch (Exception e) { logger.log(Level.SEVERE, String.format("service[%s] init fail", getName()), e); } } public void start() { try { if (!isStarted()) { logger.info(String.format("service[%s] starting", getName())); startService(); logger.info(String.format("service[%s] started", getName())); setState(started); } } catch (Exception e) { logger.log(Level.SEVERE, String.format("service[%s] start fail", getName()), e); } } public void stop() { try { if (!isStopped()) { logger.info(String.format("service[%s] stopping", getName())); stopService(); logger.info(String.format("service[%s] stopped", getName())); setState(stopped); } } catch (Exception e) { logger.log(Level.SEVERE, String.format("service[%s] stop fail", getName()), e); } } public boolean isInited() { return getState() == inited || getState() == started; } public boolean isStarted() { return getState() == started; } public boolean isStopped() { return getState() == stopped; } public final String getClazz() { return config.getClazz(); } public final String getName() { return config.getName(); } public final ServiceConfig getServiceConfig() { return config; } final void setServiceConfig(ServiceConfig config) { this.config = config; } public String toString() { return getName(); } protected abstract void initService() throws ServiceException; protected abstract void startService() throws ServiceException; protected abstract void stopService() throws ServiceException; }
launcher.startup();
public class ServiceLauncher implements IServiceLauncher { private static final String DEFAULT_AGENT_XML = "service.xml"; private static Logger logger = LoggerManager.getLogger(ServiceLauncher.class); private File configFile; private List<Service> services; private volatile boolean stop = false; public static void main(String[] args) { try { ServiceLauncher launcher = new ServiceLauncher(); launcher.startup(); launcher.shutdown(); } catch (Exception e) { e.printStackTrace(); } } public void startup() throws Exception { String configFileAttr = System.getProperty(DEFAULT_AGENT_XML); if (configFileAttr != null) { configFile = new File(configFileAttr); } else { File home = DataCenterConfig.getHome(); configFile = new File(home, "/config/" + DEFAULT_AGENT_XML); } startupService(); } public void shutdown() throws Exception { logger.info("stop services"); if (!stop) { if (services != null) for (IService service : services) { service.stop(); } } ServiceFactory.clear(); logger.info("services stopped"); } private void startupService() throws Exception { try { logger.info("start services"); constructService(); //构造实例 for (Service service : services) { setServieProperties(service); //向实例注入参数 service.init(); } for (Service service : services) { if (service.isInited()){ service.start(); } } logger.info("servers started"); } catch (Exception e) { logger.log(Level.SEVERE, "start fail", e); throw e; } } private void constructService() throws Exception { services = new ArrayList<Service>(); ServiceParser serviceParser = new ServiceParser(); List<ServiceConfig> configs = serviceParser.getServiceConfigs(configFile); for (ServiceConfig config : configs) { Class clazz = Class.forName(config.getClazz()); Service service = (Service) clazz.newInstance(); service.setServiceConfig(config); services.add(service); ServiceFactory.registerService(service); } } private void setServieProperties(IService service) throws Exception { ServiceConfig config = service.getServiceConfig(); Class clazz = service.getClass(); for (String name : config.getAttributes().keySet()) { Method method = getSetterMethod(clazz, name); if (method != null) { invokeSetterMethod(service, method, config, name); } else { Field field = getField(clazz, name); if (field != null) { setFieldValue(service, field, config, name); } } } } private void setFieldValue(IService service, Field field, ServiceConfig config, String name) throws Exception { try { field.setAccessible(true); Class parmType = field.getType(); setGlobalPropertyValue(config, name); if (parmType.equals(Boolean.TYPE)) { field.set(service, config.getBoolean(name)); } else if (parmType.equals(Integer.TYPE)) { field.set(service, config.getInt(name)); } else if (parmType.equals(Long.TYPE)) { field.set(service, config.getLong(name)); } else if (parmType.equals(Float.TYPE)) { field.set(service, config.getFloat(name)); } else if (parmType.equals(Double.TYPE)) { field.set(service, config.getDouble(name)); } else if (parmType.equals(String.class)) { field.set(service, config.getString(name)); } else if (parmType.equals(File.class)) { String path = config.getString(name); if (path != null) { File file = getAbsolutePath(path); field.set(service, file); } } else if (Service.class.isAssignableFrom(parmType)) { IService srv = ServiceFactory.getService(config.getString(name)); if (srv != null) { field.set(service, srv); } } else { throw new IllegalArgumentException("unsupport property type:" + parmType.getName() + "," + name); } } catch (Exception e) { throw new Exception("set property error:" + name + " with service " + service.getName(), e); } } private Field getField(Class<?> clazz, String name) throws Exception { try { Field field = clazz.getDeclaredField(name); return field; } catch (Exception e) { throw new Exception("set property error:" + name, e); } } private void invokeSetterMethod(IService service, Method method, ServiceConfig config, String name) throws Exception { try { Class parmType = method.getParameterTypes()[0]; setGlobalPropertyValue(config, name); if (parmType.equals(Boolean.TYPE)) { method.invoke(service, config.getBoolean(name)); } else if (parmType.equals(Integer.TYPE)) { method.invoke(service, config.getInt(name)); } else if (parmType.equals(Long.TYPE)) { method.invoke(service, config.getLong(name)); } else if (parmType.equals(Float.TYPE)) { method.invoke(service, config.getFloat(name)); } else if (parmType.equals(Double.TYPE)) { method.invoke(service, config.getDouble(name)); } else if (parmType.equals(String.class)) { method.invoke(service, config.getString(name)); } else if (parmType.equals(File.class)) { String path = config.getString(name); if (path != null) { File file = getAbsolutePath(path); method.invoke(service, file); } } else if (Service.class.isAssignableFrom(parmType)) { IService srv = ServiceFactory.getService(config.getString(name)); if (srv != null) { method.invoke(service, srv); } } else { throw new IllegalArgumentException("unsupport property type:" + parmType.getName() + "," + name); } } catch (Exception e) { throw new Exception("set property error:" + name + " with service " + service.getName(), e); } } private File getAbsolutePath(String path) { File file = new File(path); if (!file.isAbsolute()) { file = new File(DataCenterConfig.getHome(), file.getPath()); } return file; } private void setGlobalPropertyValue(ServiceConfig config, String name) { String value = config.getAttribute(name); if (value.startsWith("$") && value.length() > 1) { String key = value.substring(1); String trueValue = DataCenterConfig.getDatacenterConfig().getProperty(key); config.put(name, trueValue); } } /** * 返回第一个遇到的合适的setter方法 */ private Method getSetterMethod(Class clazz, String methodName) { methodName = getSetterName(methodName); for (Method method : clazz.getMethods()) { if (method.getName().equals(methodName) && method.getReturnType() == void.class && !Modifier.isStatic(method.getModifiers()) && method.getParameterTypes().length == 1) { return method; } } return null; } private String getSetterName(String name) { char firstChar = name.charAt(0); name = "set" + Character.toUpperCase(firstChar) + "" + name.substring(1); return name; }
public class ServiceConfig { private String clazz; private String name; private Map<String, String> attributes = new HashMap<String, String>(); public String getClazz() { return clazz; } public void setClazz(String clazz) { this.clazz = clazz; } public String getName() { return name; } void setName(String name) { this.name = name; } public Map<String, String> getAttributes() { return attributes; } public int getInt(String name) { return Integer.valueOf(getAttribute(name)); } public long getLong(String name) { return Long.valueOf(getAttribute(name)); } public String getString(String name) { return getAttribute(name); } public float getFloat(String name) { return Float.valueOf(getAttribute(name)); } public double getDouble(String name) { return Double.valueOf(getAttribute(name)); } public boolean getBoolean(String name) { return Boolean.valueOf(getAttribute(name)); } public void put(String name, int value) { attributes.put(name, String.valueOf(value)); } public void put(String name, float value) { attributes.put(name, String.valueOf(value)); } public void put(String name, double value) { attributes.put(name, String.valueOf(value)); } public void put(String name, long value) { attributes.put(name, String.valueOf(value)); } public void put(String name, boolean value) { attributes.put(name, String.valueOf(value)); } public void put(String name, String value) { attributes.put(name, value); } public String getAttribute(String name) { return attributes.get(name); } public void putAttribute(String name, String value) { attributes.put(name, value); } }
加载插件模块
PluginManager manager = new PluginManager();
manager.init();
manager.start();
public class PluginManager { protected Logger logger = LoggerManager.getLogger(getClass()); public static final String PLUGIN_LISTS_XML = "plugin-lists.xml"; private static final String XML_PLUGIN = "/plugins//plugin"; private File pluginsPath = new File(DataCenterConfig.getHome(), "plugins"); private Map<String, IPluginModule> plugins = new ConcurrentHashMap<String, IPluginModule>(); private static final List<IPluginActuator> startActuators = new LinkedList<IPluginActuator>(); private static final List<IPluginActuator> stopActuators = new LinkedList<IPluginActuator>(); static { // 1. 创建执行器实例 ExtensionActuator extension = new ExtensionActuator(); ActivateActuator activate = new ActivateActuator(); // 2. 注册启动执行器 startActuators.add(extension); startActuators.add(activate); // 3. 注册关闭执行器 stopActuators.add(activate); stopActuators.add(extension); } /** * 初始化的时候安装所有的插件,插件可以被卸载 */ public void init() throws Exception { installPlugins(new File(pluginsPath, PLUGIN_LISTS_XML)); } public void start() throws Exception{ for (IPluginModule plugin : plugins.values()) { startPlugin(plugin); } } private void startPlugin(IPluginModule plugin) { IPluginActivator activator = plugin.getPluginActivator(); if (activator == null) { return; } int state = activator.getState(); if (state == IPluginActivator.RUNNING || state == IPluginActivator.STARTING) { // 只要插件的状态不是RESOLVER, return; // 则不能启动该插件,因为该插件可能正在停止或者正在启动过程中或者已经启动 } try { for (IPluginActuator actuator : startActuators) { actuator.start(plugin); } } catch (RuntimeException e) { logger.log(Level.SEVERE, "Initialize plugin actuator fail", e); throw e; } } private void stopPlugin(IPluginModule plugin) { logger.info("stoping plugin:" + plugin.getPluginName()); IPluginActivator activator = plugin.getPluginActivator(); if (activator == null) { return; } int state = activator.getState(); if (state == IPluginActivator.STOPPED || state == IPluginActivator.STOPPING) { // 只要插件的状态不是RESOLVER, return; // 则不能启动该插件,因为该插件可能正在停止或者正在启动过程中或者已经启动 } try { for (IPluginActuator actuator : stopActuators) { actuator.stop(plugin); } } catch (RuntimeException e) { logger.log(Level.SEVERE, "stop plugin actuator fail", e); throw e; } logger.info("stoped plugin:" + plugin.getPluginName()); } public void reloadPlugin(String pluginName) throws Exception { IPluginModule plugin = plugins.get(pluginName); if(plugin != null) { reloadPlugin(plugin); } } private void reloadPlugin(IPluginModule plugin) throws Exception { String pluginName = plugin.getPluginName(); logger.info("reload plugin " + pluginName); if (plugins.get(pluginName) != null) { unInstallPluin(pluginName); startPlugin(loadPlugin(plugin.getPluginPath())); } } public void destory() throws Exception { for (IPluginModule plugin : getPlugins()) { stopPlugin(plugin); plugin.unload(); } plugins.clear(); } public void installPlugin(String folder) throws Exception { IPluginModule plugin = loadPlugin(folder, null); if (plugin != null) { plugins.put(plugin.getPluginName(), plugin); PluginContext.addPluginModule(plugin); } } public void unInstallPluin(String pluginName) throws Exception { IPluginModule plugin = plugins.get(pluginName); //先停止插件,然后卸载插件 stopPlugin(plugin); if(plugin != null) { plugin.unload(); } plugins.remove(pluginName); } private void installPlugins(File path) throws Exception { XMLBuilder builder = XMLBuilder.createBuilder(path); NodeList pluginNodes = builder.findNodeList(XML_PLUGIN); for (int i = 0; i < pluginNodes.getLength(); i++) { Node node = pluginNodes.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { String folder = XMLBuilder.getAttribute(node, "folder"); String enable = XMLBuilder.getAttribute(node, "enable"); String filePath = XMLBuilder.getAttribute(node, "path"); if (Boolean.valueOf(enable)) { IPluginModule plugin = loadPlugin(folder, filePath); if(plugin != null) { plugins.put(plugin.getPluginName(), plugin); PluginContext.addPluginModule(plugin); } } } } } private IPluginModule loadPlugin(String folder, String filePath) { if(StringUtil.isNullOrEmpty(filePath)) { File pluginFolder = new File(pluginsPath, folder); return loadPlugin(pluginFolder); } else { File pluginFolder = new File(filePath, folder); return loadPlugin(pluginFolder); } } private IPluginModule loadPlugin(File pluginFolder) { logger.info("start load plugin:" + pluginFolder.getName()); if (pluginFolder.exists() && pluginFolder.isDirectory()) { IPluginModule plugin = new PluginModule(); plugin.load(pluginFolder); logger.info("plugin loaded:" + pluginFolder.getName()); return plugin; } else { logger.severe("plugin folder error:" + pluginFolder.getName()); return null; } } public Collection<IPluginModule> getPlugins() { return Collections.unmodifiableCollection(plugins.values()); } public File getPluginsPath() { return pluginsPath; } public void setPluginsPath(File pluginsPath) { this.pluginsPath = pluginsPath; } }
类装载记录和application,plugin摘要
最新推荐文章于 2022-10-02 12:41:47 发布