类装载记录和application,plugin摘要

        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();
	}
}


从配置文件实例化模型

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;
}
lServiceLauncher launcher = new ServiceLauncher();
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;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值