자바 동적 에이전트 원리 에 대한 간단 한 설명

자바 의 동적 프 록 시 는 Proxy.newInstance(classloader,interfaces,invocationHandler)방법 을 사용 합 니 다.
이 방법 은 다음 과 같은 조작 을 한다.
classloader 를 프 록 시 0 의 정의 클래스 로 메모리 에 프 록 시 0 클래스 를 불 러 오고 interfaces 의 모든 인 터 페 이 스 를 실현 하 며 invocationHandler 를 프 록 시 에 전송 합 니 다.

interface Bussiness {
	public void doBussiness();
}

public class BussinessImpl implements Bussiness {
	@Override
	public void doBussiness() {
		System.out.println("i do bussiness");
	}
}

public class BussinessInf implements InvocationHandler {
	private Object obj;

	public BussinessInf(Object obj) {
		this.obj = obj;
	}

	@Override
	public Object invoke(Object proxy, Method m, Object[] args)
			throws Throwable {
		System.out.println(proxy.getClass().getName());
		System.out.println("do something before bussiness");

		return m.invoke(obj, args);
	}
}

public class TestMain {
	public static void main(String[] args) {
		Bussiness b = new BussinessImpl();
		BussinessInf proxy = new BussinessInf(b);
		
		Bussiness b1 = (Bussiness) 

Proxy.newProxyInstance(b.getClass().getClassLoader()	, b.getClass().getInterfaces(),proxy);
		System.out.println(b1.getClass().getName());
// proxytest.$Proxy0
		b1.doBussiness();
	}
}

즉,인 터 페 이 스 를 정의 하 는 방법 을 프 록 시 에 의뢰 했 고 프 록 시 는 인터페이스의 모든 방법 을 실현 했다.
Proxy 내부 에서 InvocationHandler 를 사용 하여 모든 인 터 페 이 스 를 호출 하 는 방법 입 니 다.이 handler 는 우리 가 작성 한 프 록 시 구현 논리 입 니 다.
ps:Proxy 0 클래스 바이트 코드 를 가 져 오 면 jdk 의 classloader 를 수정 할 수 있 는 defineclass 방법 을 가 져 옵 니 다.바이트 코드 를 불 러 올 때 byte 배열 을 파일 에 임시로 저장 합 니 다.아니면 클 라 스 로 더 가 프 록 시 뉴 인 스 턴 스 로 들 어 오 는 방법 을 스스로 실현 하 는 것 입 니 다.
그리고springaop 에는 cglib 라 는 실현 방식 이 있 습 니 다.
cglib 는 계승 류 의 형식 을 통 해 하위 클래스 를 동적 으로 생 성 합 니 다.
그러나 상속 류 의 방식 은 op 이 부모 클래스 의 final 방법 을 차단 할 수 없습니다.
op 이 부모 클래스 를 차단 하 는 final 방법 을 원한 다 면 asm 바이트 와 같은 폭력 수단 을 사용 할 수 밖 에 없습니다.

좋은 웹페이지 즐겨찾기