microkernel architecture

The microkernel architecture pattern allows you to add additional application features as plug-ins to the core application, providing extensibility as well as feature separation and isolation. The microkernel architecture pattern consists of two types of architecture components: a core system and plug-in modules. Application logic is divided between independent plug-in modules and the basic core system, providing extensibility, flexibility, and isolation of application features and custom processing logic.

1:  Oriented-Interface Plug-in development

2:  Using Interceptor to develop Plug-in

3:  Poxy or Reflection also can be used in Plug-in development (InvocationHandler)

https://blog.csdn.net/huxiaoyonglan1/article/details/72956184

https://blog.csdn.net/danchu/article/details/70238002

public class JavassistProxyFactory extends AbstractProxyFactory {	
	@SuppressWarnings("unchecked")
	public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
		return (T) Proxy.getProxy(interfaces).newInstance(
		           new InvokerInvocationHandler(invoker)
				);
	}

	public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
		final Wrapper wrapper = Wrapper.getWrapper(
		              proxy.getClass().getName().indexOf('$') < 0 ? 
					  proxy.getClass() : type);
		return new AbstractProxyInvoker<T>(proxy, type, url) {
			@Override
			protected Object doInvoke(T proxy, String methodName, 
									  Class<?>[] parameterTypes, 
									  Object[] arguments) throws Throwable {
				return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
			}
		};
	}
}
public static <T> T create(Class<T> interfaceClass) {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class<?>[]{interfaceClass},new ObjectProxy<T>(interfaceClass)
        );
    }

    public static <T> IAsyncObjectProxy createAsync(Class<T> interfaceClass) {
        return new ObjectProxy<T>(interfaceClass);
    }

public class ObjectProxy<T> implements InvocationHandler, IAsyncObjectProxy {
    private static final Logger LOGGER = LoggerFactory.getLogger(ObjectProxy.class);
    private Class<T> clazz;

    public ObjectProxy(Class<T> clazz) {
        this.clazz = clazz;
    }

    //for synchronized call, package the call with classname, method, arguments 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class == method.getDeclaringClass()) {
            String name = method.getName();
            if ("equals".equals(name)) {
                return proxy == args[0];
            } else if ("hashCode".equals(name)) {
                return System.identityHashCode(proxy);
            } else if ("toString".equals(name)) {
                return proxy.getClass().getName() + "@" +
                        Integer.toHexString(System.identityHashCode(proxy)) +
                        ", with InvocationHandler " + this;
            } else {
                throw new IllegalStateException(String.valueOf(method));
            }
        }

        //package the classname, method, types of arguments and arguments,additional request id
        RpcRequest request = new RpcRequest();
        request.setRequestId(UUID.randomUUID().toString());
        request.setClassName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setParameterTypes(method.getParameterTypes());
        request.setParameters(args);
        
        // Debug
        LOGGER.debug(method.getDeclaringClass().getName());
        LOGGER.debug(method.getName());
        for (int i = 0; i < method.getParameterTypes().length; ++i) {
            LOGGER.debug(method.getParameterTypes()[i].getName());
        }
        for (int i = 0; i < args.length; ++i) {
            LOGGER.debug(args[i].toString());
        }

        //get one client from list of client
        RpcClientHandler handler = ConnectManage.getInstance().chooseHandler();
        
        //send rpc message to rpc server and wait for results
        RPCFuture rpcFuture = handler.sendRequest(request);
        return rpcFuture.get();
    }

    @Override
    public RPCFuture call(String funcName, Object... args) {
        RpcClientHandler handler = ConnectManage.getInstance().chooseHandler();
        RpcRequest request = createRequest(this.clazz.getName(), funcName, args);
        RPCFuture rpcFuture = handler.sendRequest(request);
        return rpcFuture;
    }
}
public class RpcClient implements InvocationHandler {	
	
	@SuppressWarnings("unchecked")
	public <T> T proxy(Class<T> interfaceClass) throws Throwable {
		if (!interfaceClass.isInterface()) {
			throw new IllegalArgumentException(interfaceClass.getName()
					+ " is not an interface");
		}
		return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class<?>[] { interfaceClass }, this);
	}
	
	@Override
	public RpcClient interfaceClass(Class<?> interfaceClass) {
		// TODO Auto-generated method stub
		this.interfaceClass=interfaceClass;
		return this;
	}

	@Override
	public RpcClient version(String version) {
		// TODO Auto-generated method stub
		this.version=version;
		return this;
	}

	@Override
	public RpcClient clientTimeout(int clientTimeout) {
		// TODO Auto-generated method stub
		this.timeout=clientTimeout;
		return this;
	}

	@Override
	public RpcConsumer hook(ConsumerHook hook) {
		// TODO Auto-generated method stub
		this.hook=hook;
		return this;
	}

	@Override
	public Object instance() {
		try {
			return proxy(this.interfaceClass);
		}
		catch (Throwable e) 
		{
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void asynCall(String methodName) {
		 asynCall(methodName, null);
	}

	@Override
	public <T extends ResponseCallbackListener> void asynCall(String methodName, T callbackListener) {		
		this.asyncMethods.put(methodName, callbackListener);
		this.connection.setAsyncMethod(asyncMethods);		
		for (RpcConnection conn:connection_list) 
		{
			conn.setAsyncMethod(asyncMethods);
		}
	}

	@Override
	public void cancelAsyn(String methodName) {
		this.asyncMethods.remove(methodName);
		this.connection.setAsyncMethod(asyncMethods);
		for (RpcConnection conn:connection_list) 
		{
			conn.setAsyncMethod(asyncMethods);
		}
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		List<String> parameterTypes = new LinkedList<String>();
		for (Class<?> parameterType : method.getParameterTypes()) {
			parameterTypes.add(parameterType.getName());
		}
		RpcRequest request = new RpcRequest();
		request.setRequestId(UUID.randomUUID().toString());
        request.setClassName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setParameterTypes(method.getParameterTypes());
        request.setParameters(args);
        if(hook!=null)
        	hook.before(request);
		RpcResponse response = null;
		try
		{
			request.setContext(RpcContext.props);
			response = (RpcResponse) select().Send(request,asyncMethods.containsKey(request.getMethodName()));
			if(hook!=null)
            	hook.after(request);
			
			if(!asyncMethods.containsKey(request.getMethodName())&&response.getExption()!=null)
			{				
				Throwable e=(Throwable) Tool.deserialize(response.getExption(),response.getClazz());
				throw e.getCause();
			}
		}
		catch (Throwable t)
		{	
			//t.printStackTrace();
			//throw new RuntimeException(t);
			throw t;
		}
		finally
		{
//			if(asyncMethods.containsKey(request.getMethodName())&&asyncMethods.get(request.getMethodName())!=null)
//			{
//				cancelAsyn(request.getMethodName());
//			}
		}
		if(response==null)
		{
			return null;
		}
		else if (response.getErrorMsg() != null) 
		{
			throw response.getErrorMsg();
		} 
		else 
		{
			return response.getAppResponse();
		}		
	}
}
public class ProxyFactory implements MethodInterceptor {  
   
    private Object obj;  
    public Object createProxy(Object target) {  
        this.obj = target;  
        Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(this.obj.getClass());
        enhancer.setCallback(this);  
        enhancer.setClassLoader(target.getClass().getClassLoader());  
        return enhancer.create();  
    }  
  
    @Override  
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {  
        Object result = null;  
        try {  
             
            before();  
            result = proxy.invokeSuper(obj, args);               
            after();  
        } catch (Exception e) {  
            exception();  
        }finally{  
            beforeReturning();  
        }  
        return result;  
    } 
}

Hello hello = new Hello();  
ProxyFactory cglibProxy = new ProxyFactory();  
Hello proxy = (Hello) cglibProxy.createProxy(hello);  
String result=proxy.sayHello(true);          

//////////////////////////////////////////////////////
  Enhancer enhancer = new Enhancer();  
  enhancer.setSuperclass(SampleClass.class);  
  enhancer.setCallback(new FixedValue() {  
    @Override  
    public Object loadObject() throws Exception {  
      return "Hello cglib!";  
    }  
  });  
  SampleClass proxy = (SampleClass) enhancer.create();

////////////////////////////////////////////////////////
  Enhancer enhancer = new Enhancer();  
  enhancer.setSuperclass(SampleClass.class);  
  enhancer.setCallback(new InvocationHandler() {  
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
        throws Throwable {  
      if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {  
        return "Hello cglib!";  
      } else {  
        throw new RuntimeException("Do not know what to do.");  
      }  
    }  
  });  
  SampleClass proxy = (SampleClass) enhancer.create();  

/////////////////////////////////////////////////////////////////
  Enhancer enhancer = new Enhancer();  
  enhancer.setSuperclass(SampleClass.class);  
 enhancer.setCallbackFilter(new filter());
  enhancer.setCallback(new MethodInterceptor() {  
    @Override  
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)  
        throws Throwable {  
      if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {  
        return "Hello cglib!";  
      } else {  
        return proxy.invokeSuper(obj, args);  
      }  
    }  
  });  
  SampleClass proxy = (SampleClass) enhancer.create();
//////////////////////////////////////////////////////////////////

https://www.jianshu.com/p/20203286ccd9

原文地址:https://www.cnblogs.com/iiiDragon/p/9628755.html