microkernel architecture - Proxy
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