Spring AOP 의 정적 에이전트 와 동적 에이전트 사용법 상세 설명

대리 란 무엇 입 니까?
특정한 대상 을 위해 프 록 시 대상 을 만 듭 니 다.프로그램 은 원래 의 대상 을 직접 사용 하지 않 고 만 든 프 록 시 대상 으로 원래 의 대상 을 제어 합 니 다.프 록 시 클래스 와 같은 중간 층 을 통 해 의뢰 대상 에 대한 직접 방문 을 효과적으로 통제 할 수 있 고 위 탁 류 대상 을 잘 숨 기 고 보호 할 수 있 으 며 서로 다른 제어 전략 을 실시 하기 위해 공간 을 미리 남 길 수 있 습 니 다.
정적 에이전트 란 무엇 입 니까?
프로그램 이 만 들 거나 특정 도구 에서 원본 코드 를 자동 으로 생 성 합 니 다.프로그램 이 실행 되 기 전에 프 록 시 클래스 의 class 파일 이 이미 존재 합 니 다.
목표 클래스 와 프 록 시 클래스 를 같은 인 터 페 이 스 를 실현 하여 프 록 시 클래스 가 실제 클래스 대상 을 가지 도록 한 다음 에 프 록 시 클래스 방법 에서 실제 클래스 방법 을 호출 하고 실제 클래스 방법 을 호출 하 는 전후 에 우리 가 필요 로 하 는 기능 확장 코드 를 추가 하여 강화 하 는 목적 을 달성 하도록 한다.
장점.
4.567917.대 리 는 클 라 이언 트 로 하여 금 실현 류 가 무엇 인지,어떻게 하 는 지 알 필요 가 없 게 하고 클 라 이언 트 는 대리 만 알 면 된다4.567917.기능 증가 에 편리 하고 업무 논리 확장결점.
4.567917.대리 류 에 대량의 불필요 한 코드 가 자주 나타 나 는데 확장 과 유지 에 매우 불리 하 다.
4.567917.인터페이스 에 하나의 방법 이 추가 되면 모든 실현 류 가 이 방법 을 실현 해 야 하 는 것 을 제외 하고 모든 대리 류 도 이 방법 을 실현 해 야 한다.코드 유지보수 의 복잡 도 를 증가 시 켰 습 니 다사례 시범
PayService.java(인터페이스)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  *     
  * @param outTradeNo    
  * @return
  */
 String callback(String outTradeNo);

 /**
  *   
  * @param userId   id
  * @param productId   id
  * @return
  */
 int save(int userId,int productId);
}
PayServiceImpl.java(인터페이스 구현 클래스)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("    PayServiceImpl       callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("    PayServiceImpl       save");
  return productId;
 }
}
StaticProxyPayServiceImpl.java(인터페이스 구현 클래스,정적 에이전트)

package net.cybclass.sp.proxy;

public class StaticProxyPayServiceImpl implements PayService{
 private PayService payService;
 public StaticProxyPayServiceImpl(PayService payService)
 {
  this.payService=payService;
 }
 public String callback(String outTradeNo) {
  System.out.println("StaticProxyPayServiceImpl callback begin");
  String result=payService.callback(outTradeNo);
  System.out.println("StaticProxyPayServiceImpl callback end");
  return result;
 }

 public int save(int userId, int productId) {
  System.out.println("StaticProxyPayServiceImpl save begin");
  int id = payService.save(userId, productId);
  System.out.println("StaticProxyPayServiceImpl save end");
  return id;
 }
}
시범 을 보이다

동적 대리 란 무엇 입 니까?
프로그램 이 실 행 될 때 반사 체 제 를 사용 하여 동적 으로 만 들 었 습 니 다.코드 를 수 동 으로 작성 할 필요 가 없습니다.
JDK 동적 에이전트
CGLIB 동적 에이전트(원리:지정 한 업무 클래스 에 하위 클래스 를 생 성하 고 그 중의 업무 방법 을 덮어 서 대 리 를 실현 하 는 것)
jdk 동적 에이전트 프레젠테이션

     ,   InvocationHandler    ,    invoke  

//Object proxy:      
//Method method:      
//Object[] args:          
public Object invoke(Object proxy, Method method, Object[] args){}
PayService.java(인터페이스)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  *     
  * @param outTradeNo    
  * @return
  */
 String callback(String outTradeNo);

 /**
  *   
  * @param userId   id
  * @param productId   id
  * @return
  */
 int save(int userId,int productId);
}
PayServiceImpl.java(인터페이스 구현 클래스)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("    PayServiceImpl       callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("    PayServiceImpl       save");
  return productId;
 }
}
JDKProxy.java(jdk 동적 에이전트 클래스)

package net.cybclass.sp.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKProxy implements InvocationHandler {
 //   
 private Object targetObject;

 /**
  *       
  * @param targetObject    
  * @return
  */
 public Object newProxyInstance(Object targetObject) {
  this.targetObject = targetObject;
  //    ,              
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
    targetObject.getClass().getInterfaces(), this);
 }

 /**
  * JDK    
  *
  * @param proxy       
  * @param method       
  * @param args           
  * @return
  * @throws Throwable
  */
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  Object result = null;
  try {
   System.out.println("  JDK      "+method.getName()+",     begin");
   result = method.invoke(targetObject, args);
   System.out.println("  JDK      "+method.getName()+",     end");
  } catch (Exception ex) {
   ex.printStackTrace();
  }
  return result;
 }
}

CGLIB 동적 에이전트 프레젠테이션
PayService.java(인터페이스)

package net.cybclass.sp.proxy;

public interface PayService {
 /**
  *     
  * @param outTradeNo    
  * @return
  */
 String callback(String outTradeNo);

 /**
  *   
  * @param userId   id
  * @param productId   id
  * @return
  */
 int save(int userId,int productId);
}
PayServiceImpl.java(인터페이스 구현 클래스)

package net.cybclass.sp.proxy;

public class PayServiceImpl implements PayService{
 public String callback(String outTradeNo) {
  System.out.println("    PayServiceImpl       callback");
  return outTradeNo;
 }

 public int save(int userId, int productId) {
  System.out.println("    PayServiceImpl       save");
  return productId;
 }
}
CGLIBProxy.java(CGLIB 동적 에이전트 클래스)

package net.cybclass.sp.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGLIBProxy implements MethodInterceptor {
 //   
 private Object targetObject;
 //    
 public Object newProxyInstance(Object targetObject){
  this.targetObject=targetObject;
  Enhancer enhancer=new Enhancer();
  //        (   )
  enhancer.setSuperclass(this.targetObject.getClass());
  //      
  enhancer.setCallback(this);
  //    (    )
  return enhancer.create();
 }
 public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
  Object result=null;
  try
  {
   System.out.println("  CGLIB      "+method.getName()+",     begin");
   result=methodProxy.invokeSuper(o,args);
   System.out.println("  CGLIB      "+method.getName()+",     end");
  }
  catch (Exception ex){
   ex.printStackTrace();
  }
  return result;
 }
}

총결산
동적 프 록 시 와 정적 프 록 시 를 비교 하면 가장 큰 장점 은 인터페이스 에서 설명 한 모든 방법 이 호출 프로세서 의 집중 적 인 방법 으로 처리 되 고 디 결합 과 유지 보수 가 용이 하 다 는 것 이다.
두 동적 에이전트 의 차이
  • JDK 동적 에이전트:목표 대상 에 게 하나의 인 터 페 이 스 를 실현 하도록 요구 하지만 가끔 은 목표 대상 이 하나의 단독 대상 일 뿐 어떠한 인터페이스 도 실현 하지 못 할 때 CGLIB 동적 에이전트 를 사용 할 수 있다
  • JDK 동적 대 리 는 자체 적 인 것 이 고 CGLIB 는 제3자 가방 을 도입 해 야 한다
  • CGLIB 동적 에이전트,메모리 에 하위 클래스 대상 을 구축 하여 대상 기능 에 대한 확장 을 실현 합 니 다CGLIB 동적 대 리 는 계승 을 바탕 으로 대 리 를 실현 하기 때문에 final 류,private 방법 과 static 방법 에 대해 대 리 를 실현 할 수 없습니다Spring AOP 의 에이전트 가 사용 하 는 기본 정책
  • 대상 이 클래스 인 터 페 이 스 를 실현 하면 기본적으로 JDK 동적 대 리 를 사용 합 니 다
  • 대상 이 인 터 페 이 스 를 실현 하지 못 하면 CGLIB 로 동적 대 리 를 한다
  • 여기 서 Spring AOP 의 정적 에이전트 와 동적 에이전트 사용법 에 대한 상세 한 설명 을 소개 합 니 다.더 많은 Spring AOP 정적 에이전트 동적 에이전트 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 저 를 많이 응원 해 주세요!

    좋은 웹페이지 즐겨찾기