/** * Creates a map of concrete json request handler invokers keyed by <b><code> * <service-name>/<op-name></code></b>. * * @param handlerInstance The request handler instance to generate invokers for * @return the map of generated invokers */ public static Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> createInvokers( Object handlerInstance) { if (handlerInstance == null) throw new IllegalArgumentException("The passed handlerInstance was null"); Map<String, AbstractJSONRequestHandlerInvoker> subInvokerMap = new HashMap<String, AbstractJSONRequestHandlerInvoker>(); Map<String, Map<String, AbstractJSONRequestHandlerInvoker>> invokerMap = invokerCache.get(handlerInstance.getClass()); if (invokerMap != null) { LOG.info("Found Cached Invokers for [{}]", handlerInstance.getClass().getName()); return invokerMap; } invokerMap = new HashMap<String, Map<String, AbstractJSONRequestHandlerInvoker>>(1); LOG.info("Generating Invokers for [{}]", handlerInstance.getClass().getName()); JSONRequestService svc = handlerInstance.getClass().getAnnotation(JSONRequestService.class); final String invokerServiceKey = svc.name(); final String invokerServiceDescription = svc.description(); invokerMap.put(invokerServiceKey, subInvokerMap); ClassPool cp = new ClassPool(); cp.appendClassPath(new ClassClassPath(handlerInstance.getClass())); cp.appendClassPath(new ClassClassPath(AbstractJSONRequestHandlerInvoker.class)); cp.importPackage(handlerInstance.getClass().getPackage().getName()); Set<ClassLoader> classPathsAdded = new HashSet<ClassLoader>(); Set<String> packagesImported = new HashSet<String>(); try { final CtClass jsonRequestCtClass = cp.get(JSONRequest.class.getName()); final CtClass parent = cp.get(AbstractJSONRequestHandlerInvoker.class.getName()); CtClass targetClass = cp.get(handlerInstance.getClass().getName()); Collection<Method> methods = getTargetMethods(handlerInstance.getClass()); for (Method m : methods) { final JSONRequestHandler jsonHandler = m.getAnnotation(JSONRequestHandler.class); final String opName = jsonHandler.name(); final String opDescription = jsonHandler.description(); final RequestType opType = jsonHandler.type(); int targetMethodHashCode = m.toGenericString().hashCode(); final String className = String.format( "%s-%s%s-%s-%s", handlerInstance.getClass().getName(), invokerServiceKey, opName, "ServiceInvoker", targetMethodHashCode); final CtClass invokerClass = cp.makeClass(className, parent); CtField ctf = new CtField(targetClass, "typedTarget", invokerClass); ctf.setModifiers(ctf.getModifiers() | Modifier.FINAL); invokerClass.addField(ctf); for (CtConstructor parentCtor : parent.getConstructors()) { CtConstructor invokerCtor = CtNewConstructor.copy(parentCtor, invokerClass, null); invokerCtor.setBody( "{ super($$); typedTarget = (" + handlerInstance.getClass().getName() + ")$1; }"); invokerClass.addConstructor(invokerCtor); } CtMethod invokerMethod = CtNewMethod.copy( parent.getDeclaredMethod("doInvoke", new CtClass[] {jsonRequestCtClass}), invokerClass, null); StringBuilder b = new StringBuilder("{this.typedTarget.").append(m.getName()).append("($1"); final Class<?>[] ptypes = m.getParameterTypes(); final int remainingParamCount = ptypes.length - 1; // Set<Class<?>> classPathsAdded = new HashSet<Class<?>>(); // Set<String> packagesImported = new HashSet<String>(); if (remainingParamCount > 0) { for (int i = 0; i < remainingParamCount; i++) { final Class<?> type = ptypes[i + 1]; if (type.getName().contains("UniqueIdType")) { System.err.println("Comin Up...."); } if (type.isPrimitive()) { b.append(", (").append(type.getName()).append(") null"); } else { if (classPathsAdded.add(type.getClassLoader())) { cp.appendClassPath(new LoaderClassPath(type.getClassLoader())); } try { Package p = type.getPackage(); if (p == null) { if (type.isArray()) { if (!type.getComponentType().isPrimitive()) { p = type.getComponentType().getPackage(); } } } if (type.isEnum()) { final String f = type.getEnclosingClass().getName() + "." + type.getSimpleName(); b.append(", (").append(f).append(") null"); String pack = type.getEnclosingClass().getPackage().getName(); if (packagesImported.add(pack)) { cp.importPackage(pack); } continue; } if (p != null) { if (packagesImported.add(p.getName())) { cp.importPackage(p.getName()); } } } catch (Exception ex) { ex.printStackTrace(System.err); } b.append(", (").append(type.getSimpleName()).append(") null"); } } } b.append(");}"); System.out.println("[" + m.getName() + "]: [" + b.toString() + "]"); // invokerMethod.setBody("{this.typedTarget." + m.getName() + "($1);}"); invokerMethod.setBody(b.toString()); invokerMethod.setModifiers(invokerMethod.getModifiers() & ~Modifier.ABSTRACT); invokerClass.addMethod(invokerMethod); // invokerClass.writeFile(System.getProperty("java.io.tmpdir") + File.separator + // "jsoninvokers"); Class<?> clazz = invokerClass.toClass( handlerInstance.getClass().getClassLoader(), handlerInstance.getClass().getProtectionDomain()); Constructor<?> ctor = clazz.getDeclaredConstructor( Object.class, String.class, String.class, String.class, String.class, RequestType.class); AbstractJSONRequestHandlerInvoker invokerInstance = (AbstractJSONRequestHandlerInvoker) ctor.newInstance( handlerInstance, invokerServiceKey, invokerServiceDescription, opName, opDescription, opType); subInvokerMap.put(opName, invokerInstance); } invokerCache.put(handlerInstance.getClass(), invokerMap); return invokerMap; } catch (Exception ex) { LOG.error( "Failed to create RequestHandlerInvoker for [{}]", handlerInstance.getClass().getName(), ex); throw new RuntimeException( "Failed to create RequestHandlerInvoker [" + handlerInstance.getClass().getName() + "]", ex); } }
public ClazzInfo classProcessing(String clazzName) throws NotFoundException, CannotCompileException { ClassPool classPool = ClassPool.getDefault(); CtClass cz = classPool.get(clazzName); classPool.importPackage(clazzName); // 继承 classPool.importPackage("java.lang.reflect.Method"); // 添加反射引用 CtClass newClass = classPool.makeClass(clazzName + "$MC_IMPL"); // 新建代理类 newClass.setSuperclass(cz); // 继承 // 构造块 CtConstructor tempC; CtConstructor[] ctConstructors = cz.getDeclaredConstructors(); newClass.addConstructor(CtNewConstructor.defaultConstructor(newClass)); for (CtConstructor c : ctConstructors) { try { tempC = CtNewConstructor.copy(c, newClass, null); tempC.setBody("{super($$);}"); newClass.addConstructor(tempC); } catch (Exception e) { // e.printStackTrace(); } } // 字段块 // CtField[] ctFields = cz.getDeclaredFields(); // for (CtField f : ctFields) // System.out.println(f.getFieldInfo().getConstantValue()); // 方法块 CtMethod[] ctMethods = cz.getDeclaredMethods(); CtMethod tempM; // 复制方法名 Map<String, Method> tempMethod = new HashMap<String, Method>(); for (CtMethod m : ctMethods) { tempMethod.put( String.format( "%s %s %s(%s);", Modifier.toString(m.getModifiers()), m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes())), null); // System.err.println(String.format("%s %s %s(%s);", Modifier.toString(m.getModifiers()), // m.getReturnType().getName(), m.getName(), Util.getParameterTypes(m.getParameterTypes()))); tempM = CtNewMethod.copy(m, newClass, null); if ("void".equals(tempM.getReturnType().getName())) tempM.setBody("{super." + tempM.getName() + "($$);}"); else tempM.setBody("{ return super." + tempM.getName() + "($$);}"); // CtNewMethod.make(src, declaring, delegateObj, delegateMethod) // 方法修改 // if (m.getName().equals("x")) { // //tempM.setBody("{$proceed($$);}", "this", "mba"); // //tempM.setBody("{n nn = new n();" + "Method a = n.class.getDeclaredMethod(\"a\", new // Class[] { Integer.TYPE });" + "a.invoke(nn, new Object[] { Integer.valueOf(1) });}"); // tempM.setBody("{Method a = n.class.getDeclaredMethod(\"axx\", new Class[] { Integer.TYPE // });}"); // } newClass.addMethod(tempM); } // 测试输出 try { newClass.writeFile("D:/Desktop"); } catch (IOException e) { e.printStackTrace(); } // Class clazz = newClass.toClass(); // System.out.println(clazz.getCanonicalName()); // DefaultCachePoolFactory.newInstance().addNFloop4Map(new ClazzInfo(clazz, tempMethod), // DefaultPool.NORNAL_BEAN, clazz.getCanonicalName()); // return clazz; return new ClazzInfo(newClass.toClass(), tempMethod); }