javassist 기반 동적 프로 그래 밍 프로 세 스 분석

오늘 dubbo 를 연구 할 때 새로운 지식 을 발 견 했 습 니 다.javassist 패 키 지 를 사용 하여 동적 프로 그래 밍 을 할 수 있 고 hibenate 도 이 패 키 지 를 사용 하여 프로 그래 밍 을 할 수 있 습 니 다.저녁 에 바 이 두 는 많은 자 료 를 가지 고 그 특성 을 코드 로 보 여 주 었 다.

package com.zhi.demo;

import java.lang.reflect.Field;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.Loader;
import javassist.Modifier;
import javassist.bytecode.AccessFlag;

/**
 * Javassist      
 *
 * @date 2019 03 11 23:00:33
 *
 */
public class JavassistTest {
  public static void main(String[] args) {
    try {
      test();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void test() throws Exception {
    System.out.println("-------------------   ------------------");
    ClassPool pool = ClassPool.getDefault();
    //    
    CtClass ct = pool.makeClass("com.zhi.Person");
    //     Cloneable  
    ct.setInterfaces(new CtClass[] { pool.makeInterface("java.lang.Cloneable") });

    //     int       
    CtField fieldId = new CtField(CtClass.intType, "id", ct);
    fieldId.setModifiers(AccessFlag.PUBLIC);
    ct.addField(fieldId);

    //          
    CtConstructor constructor1 = CtNewConstructor.make("public Person(){this.id=1;}", ct);
    ct.addConstructor(constructor1);

    //     
    CtMethod helloM = CtNewMethod
        .make("public void hello(String des){System.out.println(\"  hello  ,\"+des+\",  id \"+this.id);}", ct);
    ct.addMethod(helloM);

    //     .class       
    ct.writeFile();

    //      ,  ct.toClass() new Loader(pool).loadClass()
    Class<?> clazz = ct.toClass();
//    Class<?> clazz = new Loader(pool).loadClass("com.zhi.Person");

    //        
    System.out.println("  :" + clazz.getPackageName());
    System.out.println("  :" + clazz.getName());
    System.out.println("    :" + clazz.getSimpleName());
    System.out.println("   :" + Modifier.toString(clazz.getModifiers()));
    System.out.println("   :" + clazz.getSuperclass().getName());
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      System.out.println("    :" + field.getName() + ",    :" + field.getType() + ",   :"
          + Modifier.toString(field.getModifiers()));
    }

    //       ,   hello  
    Object ob = clazz.getDeclaredConstructor().newInstance();
    clazz.getMethod("hello", String.class).invoke(ob, "  ");

    //   (  toClass      )
    ct.defrost();

    System.out.println("-------------------   ------------------");

    //     String       
    CtField fieldName = new CtField(pool.get(String.class.getName()), "name", ct);
    fieldName.setModifiers(AccessFlag.PRIVATE);
    ct.addField(fieldName);

    //          
    CtConstructor constructor2 = new CtConstructor(new CtClass[] { pool.get(String.class.getName()) }, ct);
    constructor2.setModifiers(Modifier.PUBLIC);
    constructor2.setBody("{this.name=$1;}");
    ct.addConstructor(constructor2);

    ct.addMethod(CtNewMethod.make("public void setName(String name){this.name=name;}", ct));
    ct.addMethod(CtNewMethod.make("public String getName(){return this.name;}", ct));

    ct.writeFile();

    //    ,     ct.toClass()    ,       ct.toClass()  ,     ,       2       
    clazz = new Loader(pool).loadClass("com.zhi.Person");

    fields = clazz.getDeclaredFields();
    for (Field field : fields) {
      System.out.println("    :" + field.getName() + ",    :" + field.getType() + ",   :"
          + Modifier.toString(field.getModifiers()));
    }

    ob = clazz.getDeclaredConstructor(String.class).newInstance("  ");
    System.out.println("  getName       :" + clazz.getMethod("getName").invoke(ob));
  }
}
위의 코드 출력 결 과 는 다음 과 같 습 니 다:

-------------------   ------------------
  :com.zhi
  :com.zhi.Person
    :Person
   :public
   :java.lang.Object
    :id,    :int,   :public
  hello  ,  ,  id 1
-------------------   ------------------
    :id,    :int,   :public
    :name,    :class java.lang.String,   :private
  getName       :  
설명:
$0,$1,$2:각각 this,첫 번 째 매개 변수,두 번 째 매개 변 수 를 대표 합 니 다.
$r:값 을 되 돌려 주 는 방법 입 니 다.
$_:방법 반환 값
의존 가방

<dependency>
  <groupId>org.javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.24.1-GA</version>
</dependency>
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기