JavassistProxy implements Proxy { @Override @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> interfaceClass, Invoker proxyInvoker) { StringBuilder debug = null; if (LOGGER.isDebugEnabled()) { debug = new StringBuilder(); } try { Class clazz = PROXY_CLASS_MAP.get(interfaceClass); if (clazz == null) { String interfaceName = ClassTypeUtils.getTypeStr(interfaceClass); ClassPool mPool = ClassPool.getDefault(); mPool.appendClassPath(new LoaderClassPath(ClassLoaderUtils.getClassLoader(JavassistProxy.class))); CtClass mCtc = mPool.makeClass(interfaceName + "_proxy_" + counter.getAndIncrement()); if (interfaceClass.isInterface()) { mCtc.addInterface(mPool.get(interfaceName)); } else { throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface"); } mCtc.setSuperclass(mPool.get(java.lang.reflect.Proxy.class.getName())); CtConstructor constructor = new CtConstructor(null, mCtc); constructor.setModifiers(Modifier.PUBLIC); constructor.setBody("{super(new " + UselessInvocationHandler.class.getName() + "());}"); mCtc.addConstructor(constructor); List<String> fieldList = new ArrayList<String>(); List<String> methodList = new ArrayList<String>(); fieldList.add("public " + Invoker.class.getCanonicalName() + " proxyInvoker = null;"); createMethod(interfaceClass, fieldList, methodList); for (String fieldStr : fieldList) { if (LOGGER.isDebugEnabled()) { debug.append(fieldStr).append("\n"); } mCtc.addField(CtField.make(fieldStr, mCtc)); } for (String methodStr : methodList) { if (LOGGER.isDebugEnabled()) { debug.append(methodStr).append("\n"); } mCtc.addMethod(CtMethod.make(methodStr, mCtc)); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("javassist proxy of interface: {} \r\n{}", interfaceClass, debug != null ? debug.toString() : ""); } clazz = mCtc.toClass(); PROXY_CLASS_MAP.put(interfaceClass, clazz); } Object instance = clazz.newInstance(); clazz.getField("proxyInvoker").set(instance, proxyInvoker); return (T) instance; } catch (Exception e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("javassist proxy of interface: {} \r\n{}", interfaceClass, debug != null ? debug.toString() : ""); } throw new SofaRpcRuntimeException(LogCodes.getLog(LogCodes.ERROR_PROXY_CONSTRUCT, "javassist"), e); } }  @Override @SuppressWarnings("unchecked") T getProxy(Class<T> interfaceClass, Invoker proxyInvoker); @Override Invoker getInvoker(Object proxyObject); static Invoker parseInvoker(Object proxyObject);  }
@Test public void getProxy() throws Exception { JavassistProxy proxy = new JavassistProxy(); AbstractTestClass testClass = null; try { testClass = proxy.getProxy(AbstractTestClass.class, new TestInvoker()); } catch (Exception e) { LOGGER.info(e.getMessage()); } Assert.assertNull(testClass); TestInvoker invoker = new TestInvoker(); TestInterface testInterface = proxy.getProxy(TestInterface.class, invoker); Assert.assertNotNull(testInterface); Class clazz = testInterface.getClass().getInterfaces()[0]; Assert.assertEquals(TestInterface.class, clazz); Assert.assertTrue(Proxy.class.isAssignableFrom(testInterface.getClass())); Assert.assertFalse(Proxy.isProxyClass(testInterface.getClass())); Assert.assertEquals(proxy.getInvoker(testInterface).getClass(), TestInvoker.class); Assert.assertEquals(testInterface.toString(), invoker.toString()); Assert.assertEquals(testInterface.hashCode(), invoker.hashCode()); TestInterface another1 = proxy.getProxy(TestInterface.class, invoker); TestInterface another2 = proxy.getProxy(TestInterface.class, new TestInvoker()); Assert.assertFalse(testInterface.equals(invoker)); Assert.assertFalse(testInterface.equals(another2)); Assert.assertEquals(testInterface, another1); Assert.assertEquals(678, another1.sayNum(true)); SofaRequest request = invoker.getRequest(); Assert.assertEquals(TestInterface.class.getCanonicalName(), request.getInterfaceName()); Assert.assertEquals("sayNum", request.getMethodName()); Assert.assertEquals("boolean", request.getMethodArgSigs()[0]); Assert.assertEquals(true, request.getMethodArgs()[0]); Assert.assertNotNull(request.getMethod()); Assert.assertEquals("sayHello", another1.sayHello("xxxx")); another1.sayNoting(); Assert.assertArrayEquals(new int[] { 6, 7, 8 }, another1.sayNums(null, new HashMap())); Assert.assertNull(another1.sayNum2(1.2D)); boolean error = false; try { another1.throwbiz1(); } catch (Throwable e) { error = true; } Assert.assertFalse(error); error = false; try { another1.throwbiz2(); } catch (Throwable e) { error = true; } Assert.assertFalse(error); try { another1.throwRPC(); } catch (Throwable e) { error = true; } Assert.assertTrue(error); }