자바 디자인 모드 학습 노트:프 록 시 모드(3)

이전 글 은 JDK Proxy 방식 을 통 해 이전의 정적 대 리 를 동적 에이전트 로 전환 하 는 것 을 소개 했다.전송 문 은 다음 과 같다.
자바 디자인 모드 학습 노트:프 록 시 모드(2)
오늘 은 동적 에이전트 의 또 다른 형식 을 계속 연구 하고 있 습 니 다.Cglib 를 통 해 동적 대 리 를 실현 합 니 다.Cglib 는 유형 에 따라 대 리 를 실현 합 니 다.그의 원 리 는 대리 의 목표 류 에 대해 하나의 하위 클래스 를 생 성하 고 그 중의 방법 을 덮어 서 강 화 를 실현 하 는 것 입 니 다.왜냐하면 밑바닥 은 대리 류 를 만 드 는 것 을 바탕 으로 하 는 하위 클래스 이기 때 문 입 니 다.그래서 이것 은 JDK 동적 에이전트 류 의 결함 을 피 했다.(피 에이전트 류 는 인 터 페 이 스 를 실현 해 야 하고 JDK 동적 에이전트 의 중요 한 특징 은 에이전트 인터페이스 이다.)그러나 계승 을 사용 하기 때문에 final 수식 류 를 대리 할 수 없습니다.final 수식 류 는 계승 할 수 없 기 때 문 입 니 다.
Cglib 를 통 해 동적 대 리 를 실현 하려 면 먼저 Cglib 패 키 지 를 도입 해 야 합 니 다.

    cglib
    cglib-nodep
    2.2

우 리 는 대상 을 찾 는 예 로 먼저 대리 대상 을 설명 합 니 다.
package com.rq.pattern.proxy.dynamicproxy.cglibproxy;

/**
  * Title: WangWu
  * Description: 
  * @author RQ 
  * @date 2020 3 30 
 */
public class WangWu {

	/**
	 *      
	 */
	public void findLove() {
		
		System.out.println("       :       ");
	}

}

이 를 통 해 알 수 있 듯 이 피 대리 대상 은 인 터 페 이 스 를 실현 할 필요 가 없다.그 다음은 대 리 를 실현 하 는 유형 이다.
package com.rq.pattern.proxy.dynamicproxy.cglibproxy;

import java.lang.reflect.Method;

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

/**
  * Title: CglibMeiPo
  * Description:     
  * @author RQ 
  * @date 2020 3 30 
 */
public class CglibMeiPo implements MethodInterceptor{

	public Object getInstance(Class> clazz) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}

	private void before() {
		System.out.println("          ,      ");
	}
	
	private void after() {
		System.out.println("     ,    ,    ");
	}

	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		before();
		Object result = proxy.invokeSuper(obj, args);
		after();
		return result;
	}
}

Cglib 를 통 해 동적 대 리 를 실현 합 니 다.핵심 은 MethodInterceptor 인 터 페 이 스 를 실현 하고 intercept()방법 을 재 작성 하 는 것 입 니 다.Cglib 는 대리 류 를 생 성 할 때 Enhancer 류 를 통 해 이 루어 집 니 다.입 참 은 대리 류 입 니 다.동적 으로 생 성 된 클래스 는 대리 류 의 하위 클래스 이기 때문에 우 리 는 목표 류 를 생 성 류 의 부모 류,enhancer.setSuperclass(clazz)로 설정 합 니 다.다른 절 차 는 모두 Cglib 에서 약정 한 절차 로 약정 되 어 있다.
동적 생 성 클래스 를 강화 하려 면 증강 부분의 코드 를 intercept()방법 에 쓸 수 있 습 니 다.이 방법 은 동적 에이전트 가 생 성 한 클래스 에 의 해 자동 으로 호출 됩 니 다.예 를 들 어 상기 예 에서 before(),after()방법 은 모두 생 성 클래스 에 대한 강화 입 니 다.
Cglib 동적 대 리 를 통한 구체 적 인 사용 방법 을 살 펴 보 자.
package com.rq.pattern.proxy;

import com.rq.pattern.proxy.dynamicproxy.cglibproxy.CglibMeiPo;
import com.rq.pattern.proxy.dynamicproxy.cglibproxy.WangWu;

/**
  * Title: CglibProxyTest
  * Description: Cglib  
  * @author RQ 
  * @date 2020 3 30 
 */
public class CglibProxyTest {

	public static void main(String[] args) {
		
		CglibMeiPo meipo = new CglibMeiPo();
		WangWu wangWu = (WangWu) meipo.getInstance(WangWu.class);
		wangWu.findLove();
	}
}

실행 결 과 는 다음 과 같 습 니 다.
          ,      
       :       
     ,    ,    

정적 에이전트,JDK 방식 동적 에이전트,Cglib 방식 동적 에이 전 트 는 다음 과 같 습 니 다.
1.정적 프 록 시 는 컴 파일 할 때 class 바이트 파일 을 만 들 고 직접 사용 할 수 있 으 며 효율 이 높 습 니 다.
2.JDK 동적 대 리 는 반드시 InvocationHandler 인 터 페 이 스 를 실현 해 야 한다.invoke 를 통 해 피 위탁 류 인 터 페 이 스 를 호출 하 는 방법 은 반사 방식 을 통 해 시스템 성능 을 소모 하지만 대리 류 의 수량 을 줄 이 고 더욱 유연 하 게 사용 할 수 있다.
3.Cglib 대 리 는 인 터 페 이 스 를 실현 하지 않 고 생 성 클래스 바이트 코드 를 통 해 대 리 를 실현 합 니 다.반사 보다 약간 빠 르 고 성능 문제 가 존재 하지 않 습 니 다.그러나 cglib 는 목표 대상 을 계승 하고 재 작성 방법 이 필요 하기 때문에 목표 대상 은 final 클래스 가 될 수 없습니다.
이상 은 학습 동적 대리 모델 에서 의 학습 소감 입 니 다.서로 학습 토론 을 환영 합 니 다.

좋은 웹페이지 즐겨찾기