一个 Dynamic Proxy 的例子

最近翻出了两年前老吴让我写的一个MockFacotry , 需要是传入一个Mock的object ,代理一系列的接口,只要mock object实现其中的方法就将调用代理给mock object不然就抛 UnsupportedOperationException。现将代码记录如下:

 

  import java.lang.reflect.InvocationHandler;
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.lang.reflect.Proxy;
  import java.util.HashMap;
  import java.util.Map;
  
  public class MockFactory {
     public static Object createInstance(Object implementation, Class<?>... interfaces) {
        return Proxy.newProxyInstance(MockFactory.class.getClassLoader(), interfaces, new Handler(implementation));
     }
  
     static class Handler implements InvocationHandler {
        private Map<MethodKey, MethodInvoker> m_methods;
  
        private Object m_instance;
  
        public Handler(Object instance) {
           m_instance = instance;
           m_methods = new HashMap<MethodKey, MethodInvoker>();
  
           for (Method method : instance.getClass().getMethods()) {
              m_methods.put(new MethodKey(method), new MethodInvoker(method));
           }
        }
  
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           MethodInvoker invoker = m_methods.get(new MethodKey(method));
  
           if (invoker != null) {
              return invoker.invoke(m_instance, args);
           } else {
              throw new UnsupportedOperationException(method + " is NOT implemented in " + m_instance.getClass());
           }
        }
     }
  
     static class MethodInvoker {
        private Method m_method;
  
        public MethodInvoker(Method method) {
           m_method = method;
        }
  
        public Object invoke(Object invokerInstance, Object... args) throws Throwable {
           try {
              if (!m_method.isAccessible()) {
                 m_method.setAccessible(true);
              }
  
              return m_method.invoke(invokerInstance, args);
           } catch (InvocationTargetException e) {
              throw e.getCause();
           } catch (Exception e) {
              throw e;
           }
        }
     }
  
     static class MethodKey {
        private Method m_method;
  
        public MethodKey(Method method) {
           m_method = method;
        }
  
        @Override
        public boolean equals(Object obj) {
           if (obj instanceof MethodKey) {
              MethodKey other = (MethodKey) obj;
  
              if ((m_method.getName().equals(other.m_method.getName()))) {
                 if (m_method.getReturnType().equals(other.m_method.getReturnType())) {
                    Class<?>[] params1 = m_method.getParameterTypes();
                    Class<?>[] params2 = other.m_method.getParameterTypes();
  
                    if (params1.length == params2.length) {
                       for (int i = 0; i < params1.length; i++) {
                          if (params1[i] != params2[i]) {
                             return false;
                          }
                       }
  
                       return true;
                    }
                 }
              }
           }
  
           return false;
        }
  
        @Override
        public int hashCode() {
           int hashcode = m_method.getName().hashCode();
  
           hashcode = hashcode * 31 + m_method.getReturnType().hashCode();
           hashcode = hashcode * 31 + m_method.getParameterTypes().length;
  
           return hashcode;
        }
     }
  }

 

你可能感兴趣的:(java,dynamic proxy)