CGLib 동적 생 성 클래스 및 인 스 턴 스

2610 단어 Java
이틀 전 자바 가상 머 신 에 깊이 들 어가 읽 었 을 때 CGLib 동적 생 성 클래스 와 클래스 인 스 턴 스 를 사용 할 수 있 는 방법 이 언급 되 어 있 는 것 을 보고 CGLib 를 다운로드 해 보 았 다.
자바 가 실 행 될 때 클 라 스 바이트 코드 를 가상 컴퓨터 에 불 러 와 실행 하 는 것 은 잘 알려 져 있 습 니 다.
다음 예제 코드:
		try {
			URL url = new URL("file:/d:/test/lib/");
			URLClassLoader urlCL = new URLClassLoader(new URL[] { url });
			Class c = urlCL.loadClass("TestClassA");
			TestClassA object = (TestClassA) c.newInstance();
			object.method();
		} catch (Exception e) {
			e.printStackTrace();
		}

물론 실행 할 때 클 라 스 바이트 코드 를 동적 으로 생 성하 여 JVM 에 불 러 올 수도 있 습 니 다. CGLib 는 전형 적 인 바이트 코드 동적 생 성 도구 입 니 다.
본인 은 간단 한 테스트 를 했 습 니 다. 코드 는 다음 과 같 습 니 다.
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

abstract class BaseGen {
	protected List calledMethods = new LinkedList<>(); // property

	public int getRandomInt() { // Get a random integer
		return new Random().nextInt(10000);
	}
	
	public abstract void printClassInfo(); // abstract method to print class info
}

class DynamicGen implements MethodInterceptor {

	public static  T newInstance(Class extends BaseGen> clazz) {
		Enhancer e = new Enhancer();
		e.setSuperclass(clazz);
		e.setCallback(new DynamicGen());
		return (T) e.create(); // Generate a class object
	}

	@Override
	public Object intercept(Object obj, Method method, Object[] params, MethodProxy methodProxy) throws Throwable {
		Object ret = null;

		String name = method.getName();
		if (name.equals("getRandomInt")) { // intercept the getRandomInt
			ret = methodProxy.invokeSuper(obj, params); // call the base method
			System.out.println("Print random int: " + ret);
		} else if (name.equals("printClassInfo")) { // implement the print class info method
			System.out.println("Class: " + obj.getClass());
		}
		
		BaseGen baseGen = (BaseGen) obj;
		baseGen.calledMethods.add(name); // change the property

		return ret;
	}

}

public class GenCodeTest {
	public static void main(String[] args) {
		BaseGen worker = DynamicGen.newInstance(BaseGen.class); // generate a BaseGen instance
		int random = worker.getRandomInt();
		System.out.println("You can get an int: " + random); // call the method
		worker.printClassInfo(); // print instance class info
		System.out.println("Called injected methods: " + worker.calledMethods); // print the property
	}
}

좋은 웹페이지 즐겨찾기