使⽤javassist动态为⽅法添加注解
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.MethodInfo;
import javassist.bytecode.ParameterAnnotationsAttribute;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.ArrayMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
<!-- /artifact/org.javassist/javassist -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.25.0-GA</version>
</dependency>
Reflections reflections = new Reflections(new ConfigurationBuilder()
//指定路径URL
.forPackages(packageName)
//添加⼦类扫描⼯具
.
addScanners(new SubTypesScanner())
//添加属性注解扫描⼯具
.addScanners(new FieldAnnotationsScanner())
//添加⽅法注解扫描⼯具
.addScanners(new MethodAnnotationsScanner())
//添加⽅法参数扫描⼯具
.addScanners(new MethodParameterScanner())
);
Set<Method> methodKafkaSet3 = MethodsAnnotatedWith(KafkaListener.class);
Set<Method> methodSet = MethodsAnnotatedWith(MyListener.class);
if (!CollectionUtils.isEmpty(methodSet)) {
for (Method method : methodSet) {
try {
String className = DeclaringClass().getName();
String methodName = Name();
//指定类
ClassPool aDefault = new ClassPool();
ClassClassPath classPath = new Class());
aDefault.inrtClassPath(classPath);
CtClass ctClass = (className);
//指定⽅法
CtMethod ctMethod = DeclaredMethod(methodName);
一代人
MethodInfo methodInfo = MethodInfo();
ConstPool constPool = ConstPool();
//要添加的注解
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.tValue(elements);
methodAnnot.addMemberValue("topics", amv);
methodAnnot.addMemberValue("groupId", new StringMemberValue("bury-point-fat", constPool));
methodAttr.addAnnotation(methodAnnot);
// 添加参数注解关于读书的书签
ParameterAnnotationsAttribute parameterAtrribute = new ParameterAnnotationsAttribute(
constPool, ParameterAnnotationsAttribute.visibleTag);
Annotation paramAnnot = new Annotation("ssaging.handler.annotation.Payload", constPool); paramAnnot.addMemberValue("value", new StringMemberValue("",constPool));
Annotation[][] paramArrays = new Annotation[1][1];
paramArrays[0][0] = paramAnnot;
parameterAtrribute.tAnnotations(paramArrays);
//写⼊class⽂件
String path = DeclaringClass().getResource("").getPath();
金牌销售员
ctClass.writeFile(path);
ctClass.defrost();
}catch (Throwable e){
e.printStackTrace();
}脖子上长瘊子
}
先帝}
备注: 获取类路径和写⼊class⽂件的另⼀种⽅式:
String DeclaringClass().DeclaringClass().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.clo();
//热加载
配置jvm参数 : agentlib:jdwp=transport=dt_socket,rver=y,suspend=n,address=8000
HotSwapper hs = new HotSwapper(8000);
//⾃定义类加载器
public class MyClassLoader extends ClassLoader {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
分辨率怎么看
//得到classpath
String classPath = Resource("/").getPath();
String fileName = place(".", "/") + ".class" ;
File classFile = new File(classPath,fileName);
if(!ists()){
throw new Path() + " 不存在") ;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
ByteBuffer bf = ByteBuffer.allocate(1024) ;
FileInputStream fis = null ;
FileChannel fc = null ;
try {
fis = new FileInputStream(classFile) ;
fc = Channel() ;
ad(bf) > 0){
bf.flip() ;
bos.write(bf.array(),0 , bf.limit()) ;
bf.clear() ;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
}finally{
try {
fis.clo() ;
fc.clo() ;
} catch (IOException e) {
e.printStackTrace();
}
}
return ByteArray() , 0 , ByteArray().length) ; }
}
>寒冷的冬天