使用javassist動態為方法添加註解
阿新 • • 發佈:2021-02-02
Reflections reflections = new Reflections(new ConfigurationBuilder() //指定路徑URL .forPackages(packageName) //新增子類掃描工具 .addScanners(new SubTypesScanner()) //新增 屬性註解掃描工具 .addScanners(new FieldAnnotationsScanner()) //新增 方法註解掃描工具 .addScanners(new MethodAnnotationsScanner()) //新增方法引數掃描工具 .addScanners(new MethodParameterScanner()) ); Set<Method> methodKafkaSet3 = reflections.getMethodsAnnotatedWith(KafkaListener.class); Set<Method> methodSet = reflections.getMethodsAnnotatedWith(MyListener.class); if (!CollectionUtils.isEmpty(methodSet)) { for (Method method : methodSet) { String className = method.getDeclaringClass().getName(); String methodName = method.getName(); //指定類 ClassPool aDefault = new ClassPool(); ClassClassPath classPath = new ClassClassPath(this.getClass()); aDefault.insertClassPath(classPath); CtClass ctClass = aDefault.get(className); //指定方法 CtMethod ctMethod = ctClass.getDeclaredMethod(methodName); MethodInfo methodInfo = ctMethod.getMethodInfo(); ConstPool constPool = methodInfo.getConstPool(); //要新增的註解 AnnotationsAttribute methodAttr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag); Annotation methodAnnot = new Annotation("org.springframework.kafka.annotation.KafkaListener", constPool); // 新增方法註解 StringMemberValue[] elements = {new StringMemberValue(String.join("-", "elk-event", env), constPool)}; ArrayMemberValue amv = new ArrayMemberValue(constPool); amv.setValue(elements); methodAnnot.addMemberValue("topics", amv); methodAnnot.addMemberValue("groupId", new StringMemberValue("bury-point-fat", constPool)); methodAttr.addAnnotation(methodAnnot); ctMethod.getMethodInfo().addAttribute(methodAttr); // 新增引數註解 ParameterAnnotationsAttribute parameterAtrribute = new ParameterAnnotationsAttribute( constPool, ParameterAnnotationsAttribute.visibleTag); Annotation paramAnnot = new Annotation("org.springframework.messaging.handler.annotation.Payload", constPool); paramAnnot.addMemberValue("value", new StringMemberValue("",constPool)); Annotation[][] paramArrays = new Annotation[1][1]; paramArrays[0][0] = paramAnnot; parameterAtrribute.setAnnotations(paramArrays); ctMethod.getMethodInfo().addAttribute(parameterAtrribute); //寫入class檔案 String path = method.getDeclaringClass().getResource("").getPath(); ctClass.writeFile(path); ctClass.defrost(); } } 備註: 獲取類路徑和寫入class檔案的另一種方式: String path=method.getDeclaringClass().getResource(method.getDeclaringClass().getSimpleName()+".class").getPath(); //把生成的class檔案寫入檔案 byte[] byteArr = new byte[0]; byteArr = ctClass .toBytecode(); FileOutputStream fos = null; fos = new FileOutputStream(new File(path)); fos.write(byteArr); fos.close();