private static void replaceImplementation(CtMethod m, String src) throws Exception { removeNativeModifier(m); if (src == null || src.trim().length() == 0) { m.setBody(null); } else { src = src.trim(); if (!src.startsWith("{")) { if (!m.getReturnType().equals(CtClass.voidType) && !src.startsWith("return")) { src = "{ return ($r)($w) " + src; } else { src = "{ " + src; } } if (!src.endsWith("}")) { if (!src.endsWith(";")) { src = src + "; }"; } else { src = src + " }"; } } try { m.setBody(src); } catch (CannotCompileException e) { throw new RuntimeException("Unable to compile body " + src, e); } } }
private static void populateMetricsAndOperations( List<Class<?>> classes, Props props, boolean withNamePrefix) throws Exception { props.setHasOperations(true); props.setHasMetrics(true); for (Class<?> clazz : classes) { MBean mbean = clazz.getAnnotation(MBean.class); String prefix = withNamePrefix ? mbean.objectName() + '.' : ""; CtClass ctClass = classPool.get(clazz.getName()); CtMethod[] ctMethods = ctClass.getMethods(); for (CtMethod ctMethod : ctMethods) { ManagedAttribute managedAttr = (ManagedAttribute) ctMethod.getAnnotation(ManagedAttribute.class); ManagedOperation managedOp = (ManagedOperation) ctMethod.getAnnotation(ManagedOperation.class); Metric rhqMetric = (Metric) ctMethod.getAnnotation(Metric.class); if (rhqMetric != null) { debug("Metric annotation found " + rhqMetric); // Property and description resolution are the reason why annotation scanning is done // here. // These two fields are calculated from either the method name or the Managed* // annotations, // and so, only the infinispan side knows about that. String property = prefix + getPropertyFromBeanConvention(ctMethod); if (!rhqMetric.property().isEmpty()) { property = prefix + rhqMetric.property(); } MetricProps metric = new MetricProps(property); String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + rhqMetric.displayName() : rhqMetric.displayName(); metric.setDisplayName(displayName); metric.setDisplayType(rhqMetric.displayType()); metric.setDataType(rhqMetric.dataType()); metric.setUnits(rhqMetric.units()); if (managedAttr != null) { debug("Metric has ManagedAttribute annotation " + managedAttr); metric.setDescription(managedAttr.description()); } else if (managedOp != null) { debug("Metric has ManagedOperation annotation " + managedOp); metric.setDescription(managedOp.description()); } else { log.debug( "Metric has no managed annotations, so take the description from the display name."); metric.setDescription(rhqMetric.displayName()); } props.getMetrics().add(metric); } Operation rhqOperation = (Operation) ctMethod.getAnnotation(Operation.class); if (rhqOperation != null) { debug("Operation annotation found " + rhqOperation); String name; if (!rhqOperation.name().isEmpty()) { name = prefix + rhqOperation.name(); } else { name = prefix + ctMethod.getName(); } OperationProps operation = new OperationProps(name); String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + rhqOperation.displayName() : rhqOperation.displayName(); operation.setDisplayName(displayName); if (managedAttr != null) { debug("Operation has ManagedAttribute annotation " + managedAttr); operation.setDescription(managedAttr.description()); } else if (managedOp != null) { debug("Operation has ManagedOperation annotation " + managedOp); operation.setDescription(managedOp.description()); } else { debug( "Operation has no managed annotations, so take the description from the display name."); operation.setDescription(rhqOperation.displayName()); } Object[][] paramAnnotations = ctMethod.getParameterAnnotations(); int i = 0; for (Object[] paramAnnotationsInEach : paramAnnotations) { boolean hadParameter = false; for (Object annot : paramAnnotationsInEach) { debug("Parameter annotation " + annot); if (annot instanceof Parameter) { Parameter param = (Parameter) annot; SimpleProperty prop = new SimpleProperty(param.name()); prop.setDescription(param.description()); operation.getParams().add(prop); hadParameter = true; } } if (!hadParameter) { operation.getParams().add(new SimpleProperty("p" + i++)); } } CtClass returnType = ctMethod.getReturnType(); if (!returnType.equals(CtClass.voidType)) { if (!returnType.equals(Void.TYPE)) { SimpleProperty prop = new SimpleProperty("operationResult"); operation.setResult(prop); } } props.getOperations().add(operation); } } CtField[] ctFields = ctClass.getDeclaredFields(); for (CtField ctField : ctFields) { debug("Inspecting field " + ctField); Metric rhqMetric = (Metric) ctField.getAnnotation(Metric.class); if (rhqMetric != null) { debug("Field " + ctField + " contains Metric annotation " + rhqMetric); String property; if (!rhqMetric.property().isEmpty()) { property = prefix + rhqMetric.property(); } else { property = prefix + getPropertyFromBeanConvention(ctField); } MetricProps metric = new MetricProps(property); String displayName = withNamePrefix ? "[" + mbean.objectName() + "] " + rhqMetric.displayName() : rhqMetric.displayName(); metric.setDisplayName(displayName); metric.setDisplayType(rhqMetric.displayType()); metric.setDataType(rhqMetric.dataType()); metric.setUnits(rhqMetric.units()); ManagedAttribute managedAttr = (ManagedAttribute) ctField.getAnnotation(ManagedAttribute.class); if (managedAttr != null) { debug("Metric has ManagedAttribute annotation " + managedAttr); metric.setDescription(managedAttr.description()); } else { log.debug( "Metric has no managed annotations, so take the description from the display name."); metric.setDescription(rhqMetric.displayName()); } props.getMetrics().add(metric); } } } }
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); }
/** Generate Javassist Proxy Classes */ private static <T> void generateProxyClass( Class<T> primaryInterface, String superClassName, String methodBody) throws Exception { String newClassName = superClassName.replaceAll("(.+)\\.(\\w+)", "$1.Hikari$2"); CtClass superCt = classPool.getCtClass(superClassName); CtClass targetCt = classPool.makeClass(newClassName, superCt); targetCt.setModifiers(Modifier.FINAL); System.out.println("Generating " + newClassName); targetCt.setModifiers(Modifier.PUBLIC); // Make a set of method signatures we inherit implementation for, so we don't generate delegates // for these Set<String> superSigs = new HashSet<>(); for (CtMethod method : superCt.getMethods()) { if ((method.getModifiers() & Modifier.FINAL) == Modifier.FINAL) { superSigs.add(method.getName() + method.getSignature()); } } Set<String> methods = new HashSet<>(); Set<Class<?>> interfaces = getAllInterfaces(primaryInterface); for (Class<?> intf : interfaces) { CtClass intfCt = classPool.getCtClass(intf.getName()); targetCt.addInterface(intfCt); for (CtMethod intfMethod : intfCt.getDeclaredMethods()) { final String signature = intfMethod.getName() + intfMethod.getSignature(); // don't generate delegates for methods we override if (superSigs.contains(signature)) { continue; } // Ignore already added methods that come from other interfaces if (methods.contains(signature)) { continue; } // Ignore default methods (only for Jre8 or later) if (isDefaultMethod(intf, intfCt, intfMethod)) { continue; } // Track what methods we've added methods.add(signature); // Clone the method we want to inject into CtMethod method = CtNewMethod.copy(intfMethod, targetCt, null); String modifiedBody = methodBody; // If the super-Proxy has concrete methods (non-abstract), transform the call into a simple // super.method() call CtMethod superMethod = superCt.getMethod(intfMethod.getName(), intfMethod.getSignature()); if ((superMethod.getModifiers() & Modifier.ABSTRACT) != Modifier.ABSTRACT) { modifiedBody = modifiedBody.replace("((cast) ", ""); modifiedBody = modifiedBody.replace("delegate", "super"); modifiedBody = modifiedBody.replace("super)", "super"); } modifiedBody = modifiedBody.replace("cast", primaryInterface.getName()); // Generate a method that simply invokes the same method on the delegate if (isThrowsSqlException(intfMethod)) { modifiedBody = modifiedBody.replace("method", method.getName()); } else { modifiedBody = "{ return ((cast) delegate).method($$); }" .replace("method", method.getName()) .replace("cast", primaryInterface.getName()); } if (method.getReturnType() == CtClass.voidType) { modifiedBody = modifiedBody.replace("return", ""); } method.setBody(modifiedBody); targetCt.addMethod(method); } } targetCt.writeFile("target/classes"); }