All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.facelog.BaseServiceController Maven / Gradle / Ivy

There is a newer version: 5.3.0
Show newest version
package net.gdface.facelog;

import java.lang.reflect.InvocationTargetException;
import java.net.URI;

import net.gdface.utils.NetworkUtil;

/**
 * 本地服务进程控制器基类
 * 如果服务指定为本机服务,则尝试连接,连接不上则尝试启动
 * @author guyadong
 *
 */
public abstract class BaseServiceController implements ServiceConstant{
	protected static final long DEFAULT_TRY_INTERVAL = 2000L;
	protected static final int DEFAULT_TRY_COUNT = 10;
	protected volatile Object embeddedObject;
	protected volatile Process process;
	protected URI location;
	/** 当服务不存在时是否等待 */
	protected boolean waitIfAbsent = false;
	/** 尝试连接服务的次数 */
	protected int tryCountLimit = DEFAULT_TRY_COUNT;
	/** 尝试连接服务的时间间隔(毫秒) */
	protected long tryInterval = DEFAULT_TRY_COUNT;
	protected BaseServiceController() {
		/** 程序结束时关闭服务 */
		Runtime.getRuntime().addShutdownHook(new Thread(){
			@Override
			public void run() {
				try {
					if(isEmbedded()){
						shutdownEmbeddedServer();
					}else{
						shutdownLocalServer();
					}
				} catch (Exception e) {
					logger.error(e.getMessage(),e);
				}
			}
		});
	}
	/**
	 * 测试服务是否可连接
	 * @return 可连接返回{@code true},否则返回{@code false}
	 */
	abstract protected boolean testConnect();
	/**
	 * 根据配置文件返回是否有启动本地服务的条件
	 * @return 可以启动本地服务返回{@code true},否则返回{@code false}
	 */
	abstract protected boolean canStartLocal();
	/**
	 * 本地服务是否为嵌入服务
	 * @return
	 */
	abstract protected boolean isEmbedded();
	/** 
	 * 启动本地(独立进程)服务
* {@link isEmbeddedServer}返回{@code false}时子类必须重写此方法 * @return 服务进程对象 */ protected Process startLocalServer(){ throw new UnsupportedOperationException(); } /** * 启动本地嵌入服务
* {@link isEmbeddedServer}返回{@code true}时子类必须重写此方法 * @return 启动嵌入式服务对象后返回的对象,如果启动的嵌入式服务不需要显式执行关闭,则返回{@code null} */ protected Object startEmbeddedServer(){ throw new UnsupportedOperationException(); } /** * 服务连接初始化,并测试连接,如果连接异常,则尝试启动本地服务器或等待服务启动 * @return 连接参数和工厂类实例是否更新 */ boolean init(){ int tryCount = this.tryCountLimit; boolean selfBind = NetworkUtil.selfBind(location.getHost()); String name = serviceName(); do{ // 测试服务器连接 if(testConnect()){ return false; } if(selfBind){ // 如果 服务指定为本地启动则尝试启动服务器 if( canStartLocal() ){ if(isEmbedded()){ embeddedObject = startEmbeddedServer(); // 嵌入式服务启动成功后不需要调用testConnect return false; }else{ process = startLocalServer(); } for(int c=0;c 0){ logger.info("waiting for activemq server...{}",tryCount); } else { throw new RuntimeException(String.format("cann't connect %s server(无法连接%s服务器) %s",name,name,location)); } try { Thread.sleep(tryInterval); } catch (InterruptedException e) { break; } }while(tryCount >0); throw new RuntimeException(String.format("cann't connect %s server(无法连接%s服务器) %s",name,name,location)); } /** * 返回服务名,默认使用当前类名,类名以"Controller"结尾时去掉此结尾转小写为服务名 * @return 服务名 */ protected String serviceName(){ String name = getClass().getSimpleName(); if(name.endsWith("Controller")){ return name.substring(0, name.lastIndexOf("Controller") ).toLowerCase(); } return name; } /** * 尝试查找{@code closeMethodNames}列表指定的close方法,如果有则执行,如果没有则输出警告信息 * @param closeMethodNames * @return 成功执行close方法则返回{@code true},否则返回{@code false} */ private boolean runCloseMethod(String ...closeMethodNames){ for(String name:closeMethodNames){ try { embeddedObject.getClass().getMethod(name).invoke(embeddedObject); embeddedObject = null; return true; } catch (NoSuchMethodException e) { continue; } catch (IllegalAccessException | SecurityException e) { e.printStackTrace(); return false; }catch (InvocationTargetException e) { e.getTargetException().printStackTrace(); return false; } } return false; } /** * 中止本地嵌入式服务
* 如果{@link #embeddedObject}为{@link AutoCloseable}实例,则执行close方法完成关闭, * 否则尝试查找{@code close()}方法,如果有则执行,如果没有则输出警告信息后返回
* 子类根据需要重写此方法 */ protected void shutdownEmbeddedServer(){ if(embeddedObject != null){ synchronized (this) { if(embeddedObject != null){ if(embeddedObject instanceof AutoCloseable){ // 如果{@link #embeddedObject}为{@link AutoCloseable}实例,则执行close方法完成关闭 try { ((AutoCloseable)embeddedObject).close(); String name = serviceName(); logger.info("shutdown {} server(关闭{}服务)",name,name); embeddedObject = null; } catch (Exception e) { e.printStackTrace(); } }else{ // 尝试查找close 方法,如果有则执行,如果没有则输出警告信息 if(!runCloseMethod("close","stop")){ logger.warn("CAN'T run shutdown embedded server,please override this method to immplement your own logic"); } } } } } } /** * 中止本地服务
* 子类根据需要重写此方法 */ protected void shutdownLocalServer(){ if(process != null){ synchronized (this) { if(process != null){ try { process.exitValue(); } catch (IllegalThreadStateException e) { String name = serviceName(); logger.info("shutdown {} server(关闭{}服务)",name,name); process.destroy(); } process = null; } } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy