스프링의 두 에이전트 JDK와 CGLIB의 차이점에 대한 간단한 설명

5401 단어 springcglibjdk
1. 원리 차이:
Java 동적 에이전트는 반사 메커니즘을 이용하여 에이전트 인터페이스를 실현하는 익명 클래스를 생성하고 구체적인 방법을 사용하기 전에 InvokeHandler를 호출하여 처리합니다.
한편, cglib 동적 에이전트는 asm 소스 패키지를 이용하여 에이전트 대상 클래스의class 파일을 불러오고 바이트 코드 생성 하위 클래스를 수정하여 처리합니다.
1. 대상 객체가 인터페이스를 구현하면 기본적으로 JDK의 동적 에이전트로 AOP 구현
2. 대상 객체가 인터페이스를 구현한 경우 CGLIB를 사용하여 AOP를 강제로 구현할 수 있음
3. 대상 객체에 인터페이스가 없으면 CGLIB 라이브러리를 사용해야 하며, 스프링은 자동으로 JDK 동적 에이전트와 CGLIB 사이를 변환한다
어떻게 CGLIB를 사용하여 AOP를 구현합니까?
(1) CGLIB 라이브러리, SPRING_ 추가HOME/cglib/.jar
(2)spring 프로필에
JDK 동적 에이전트와 CGLIB 바이트 생성의 차이점은?
(1) JDK 동적 에이전트는 인터페이스를 구현한 클래스에만 에이전트를 생성할 수 있을 뿐 클래스에 대해서는 생성할 수 없다
(2) CGLIB는 클래스 구현 에이전트로서 주로 지정된 클래스에 대해 하위 클래스를 생성하고 이를 덮어쓰는 방법
계승이기 때문에, 이 종류나 방법은final로 성명하지 않는 것이 가장 좋다
2. 코드 구현

package com.fy.spring.proxy;    
public interface UserManager {  
  public void addUser(String id, String password);  
  public void delUser(String id);  
}  

package com.fy.spring.proxy;  
  public class UserManagerImpl implements UserManager {  
  
  public void addUser(String id, String password) {  
    System.out.println(".:  UserManagerImpl.addUser() ! ");  
  
  }  
  
  public void delUser(String id) {  
    System.out.println(".:  UserManagerImpl.delUser() ! ");  
  
  }  
}  
JDK 동적 에이전트 클래스

package com.fy.spring.proxy;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
/**  
 *  
 * JDK   
 *  
 *  
 */ 
public class JDKProxy implements InvocationHandler {  
  
  private Object targetObject;//   
  
  public Object newProxy(Object targetObject) {//   
    this.targetObject = targetObject;   
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
        targetObject.getClass().getInterfaces(), this);//   
  }  
  
  public Object invoke(Object proxy, Method method, Object[] args)//invoke   
      throws Throwable {  
    checkPopedom();//   
    Object ret = null;   //    
    ret = method.invoke(targetObject, args);    // invoke ,ret   
    return ret;  
  }  
  
  private void checkPopedom() {//   
    System.out.println(".:  checkPopedom()!");  
  }  
}  
CGLibProxy 동적 프록시 클래스

package com.fy.spring.proxy;    
import java.lang.reflect.Method;  
  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
/**  
 * CGLibProxy   
 *   
 *  
 */ public class CGLibProxy implements MethodInterceptor {  
  
  private Object targetObject;// CGLib   
  
  public Object createProxyObject(Object obj) {  
    this.targetObject = obj;  
    Enhancer enhancer = new Enhancer();  
    enhancer.setSuperclass(obj.getClass());  
    enhancer.setCallback(this);  
    Object proxyObj = enhancer.create();  
    return proxyObj;//    
  }  
  
  public Object intercept(Object proxy, Method method, Object[] args,  
      MethodProxy methodProxy) throws Throwable {  
    Object obj = null;  
    if ("addUser".equals(method.getName())) {//    
      checkPopedom();//    
    }  
    obj = method.invoke(targetObject, args);  
    return obj;  
  }  
  
  private void checkPopedom() {  
    System.out.println(".:  checkPopedom()!");  
  }  
}  
테스트 클래스:

public class Client {  
  
  public static void main(String[] args) {  
  
    UserManager userManager = (UserManager) new CGLibProxy()  
        .createProxyObject(new UserManagerImpl());  
    System.out.println("-----------CGLibProxy-------------");  
    userManager.addUser("tom", "root");  
    System.out.println("-----------JDKProxy-------------");  
    JDKProxy jdkPrpxy = new JDKProxy();  
    UserManager userManagerJDK = (UserManager) jdkPrpxy  
        .newProxy(new UserManagerImpl());  
    userManagerJDK.addUser("tom", "root");  
  }  
  
}  
실행 결과:
-----------CGLibProxy-------------   
권한 확인 checkPopedom ()!   
UserManagerImpl이 사용되지 않습니다.addUser() 메서드!    
-----------JDKProxy-------------   
권한 확인 checkPopedom ()!   
UserManagerImpl이 사용되지 않습니다.addUser() 메서드! 
JDK 에이전트는 지금까지 제3자의 라이브러리가 필요하지 않고 JDK 환경만 요구하면 에이전트를 진행할 수 있습니다. 몇 가지 요구가 있습니다.
  • InvocationHandler 구현
  • Proxy 사용.newProxyInstance 프록시 객체가 생성됩니다
  • 프록시된 대상은 반드시 인터페이스를 실현해야 한다
  • CGLib은 CGLib의 라이브러리에 의존해야 하지만, 모든 인터페이스 에이전트를 실현하기 위해 클래스가 필요합니다. 지정한 클래스가 하위 클래스를 생성하고 덮어쓰는 방법입니다. 계승하지만 인터페이스 프로그래밍 환경에서 JDK를 사용하는 에이전트를 추천합니다.
    Hibernate의 차단기는 다른 인터페이스가 필요하지 않은 조건을 고려하여 Hibernate의 관련 에이전트가 CGLib를 사용하여 실행합니다.
    본고에서 기술한 것이 당신에게 도움이 되기를 바랍니다. 스프링의 두 가지 대리 JDK와 CGLIB의 차이에 대한 간단한 내용은 여기에 소개합니다.계속해서 저희 사이트에 관심을 가져주시기 바랍니다!자바를 배우고 싶으면 본 사이트에 계속 관심을 가져도 됩니다.

    좋은 웹페이지 즐겨찾기