Javassist生成class(生成类,方法,字段,注解) 侵立删

本文介绍如何利用Javassist库动态生成Spring框架的Controller类。通过代码示例,展示了如何创建类、添加字段与方法,以及如何为类和方法添加Spring注解,如@Controller、@RequestMapping等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近接触了下javassist,试着进行字节码操纵,javassist的上手还是比较简单,官方文档说的很详细,而且例子也给的蛮多。 
 

下面是自己写的一个方法,其中生成了一个经典的Spring的controller类。具体写法如下,代码已经贴上了注释。

public void makeclass(String className,String methodName, CONSTANTS.INVOKETYPE invoketype,String interfaceCode) throws NotFoundException, CannotCompileException, IOException {
        ClassPool pool = ClassPool.getDefault();
        CtClass clazz = pool.makeClass(className);
        ClassFile ccFile = clazz.getClassFile();
        ConstPool constpool = ccFile.getConstPool();

        CtClass executor = pool.get("com.javassist.test.Executor");
        CtClass requst = pool.get("javax.servlet.http.HttpServletRequest");
        CtClass response = pool.get("javax.servlet.http.HttpServletResponse");

        String fieldName = invoketype.getValue());
        // 增加字段
        CtField field = new CtField(executor,fieldName,clazz);
        field.setModifiers(Modifier.PUBLIC);
        FieldInfo fieldInfo = field.getFieldInfo();

        // 属性附上注解
        AnnotationsAttribute fieldAttr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        Annotation autowired = new Annotation("org.springframework.beans.factory.annotation.Autowired",constpool);
        fieldAttr.addAnnotation(autowired);
        fieldInfo.addAttribute(fieldAttr);
        clazz.addField(field);

        // 增加方法,javassist可以直接将字符串set到方法体中,所以使用时非常方便
        CtMethod method = new CtMethod(new CtClassType(CtClass.javaLangObject,pool),methodName,new CtClass[]{requst,response},clazz);
        method.setModifiers(java.lang.reflect.Modifier.PUBLIC);
        StringBuffer methodBody = new StringBuffer();
        methodBody.append("{return "+fieldName+".execute(\""+interfaceCode+"\",(com.javassist.test.RequestVo)$1.getAttribute(\"request\"));}");
        method.setBody(methodBody.toString());

        // 类附上注解
        AnnotationsAttribute classAttr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        Annotation controller = new Annotation("org.springframework.stereotype.Controller",constpool);
        Annotation requestMapping = new Annotation("org.springframework.web.bind.annotation.RequestMapping.RequestMapping",constpool);
        String visitPath = "/api/department";
        requestMapping.addMemberValue("value",new StringMemberValue(visitPath,constpool));
        classAttr.addAnnotation(controller);
        classAttr.addAnnotation(requestMapping);
        ccFile.addAttribute(classAttr);

        //方法附上注解
        AnnotationsAttribute methodAttr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
        //Annotation annotation3 = new Annotation("org.springframework.web.bind.annotation.RequestMapping.RequestMapping",constpool);
        requestMapping.addMemberValue("value",new StringMemberValue("/register",constpool));

        Annotation responseBody = new Annotation("org.springframework.web.bind.annotation.RequestMapping.ResponseBody",constpool);
        methodAttr.addAnnotation(requestMapping);
        methodAttr.addAnnotation(responseBody);
        MethodInfo info = method.getMethodInfo();
        info.addAttribute(methodAttr);
        clazz.addMethod(method);
        clazz.writeFile();
}

  
需要注意的是, 
1,运行在web容器或者Jboss下可能会出现找不到类,很有可能是类搜索路径的问题,可以通过增加搜索路径在试着解决问题,pool.insertClassPath(new ClassClassPath(this.getClass()));。 
2,运行在web容器或者Jboss下可能会出现类加载器问题,报ClassCastException,可以不使用默认的类加载器,也可以自定义类加载器进行加载。

原文:https://blog.youkuaiyun.com/qq_32506963/article/details/72851713 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值