java 디자인 최적화 에이전트 모델

프록시 모드는 프록시 대상을 사용하여 사용자의 요청을 완성하고 실제 대상에 대한 사용자의 접근을 차단합니다.
프록시 모델의 용도가 매우 많다. 예를 들어 안전 때문에 클라이언트가 실제 대상에 직접 접근하는 것을 차단해야 한다.또는 원격 호출에서 에이전트 대상을 사용하여 원격 방법의 기술적 세부 사항을 처리해야 한다.또는 시스템을 향상시키기 위해 진짜 대상을 봉인하여 로드 지연의 목적을 달성한다.
시스템을 시작할 때 자원을 가장 많이 소모하는 방법을 에이전트 모드로 분리하면 시스템의 시작 속도를 가속화하고 사용자의 대기 시간을 줄일 수 있다.사용자가 진정으로 검색하고 있는 것은 프록시 클래스가 실제 클래스를 불러와서 사용자의 요청을 완성하는 것입니다.이것이 바로 프록시 모드를 사용하여 로드 지연의 목적을 달성하는 것이다.
1. 정적 에이전트 구현:
테마 인터페이스:

public interface IDBQuery {
   String request();
 }
실제 주제:

public class DBQuery implements IDBQuery {
  public DBQuery(){
    try {
      Thread.sleep(10000);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  public String request() {
    return "string request";
  }
}
프록시 클래스:

public class IDBQueryProxy implements IDBQuery {
  private DBQuery dbquery; 
  public String request() {
    if(dbquery==null)
      dbquery = new DBQuery();
    return dbquery.request();
  }
}
마지막으로 주 함수:

public class ProxyText {
  public static void main(String[] args) {
    IDBQuery dbquery = new IDBQueryProxy();
    System.out.println(dbquery.request()); 
  }
}
정적 에이전트 주의, 에이전트 클래스는 실제 클래스가 공통된 인터페이스를 실현하고 에이전트 클래스는 실제 클래스의 대상을 인용하여 시간 소모 조작을 에이전트 클래스 방법에 두어 실현한다.
동적 에이전트:
동적 에이전트가 실행될 때 동적 생성 에이전트 클래스입니다.즉, 프록시 클래스의 바이트 코드가 실행될 때 현재classloader를 생성하고 불러옵니다.정적 에이전트에 비해 동적 에이전트는 진실한 주의를 위해 형식적으로 완전히 같은 봉인 클래스를 봉인할 필요가 없다. 만약에 주제 인터페이스가 많다면 모든 인터페이스에 에이전트 방법을 쓰는 것은 매우 번거롭다. 만약에 인터페이스가 변동되면 진실 클래스와 에이전트 클래스는 모두 변해야 하기 때문에 시스템 유지보수에 불리하다.그 다음에 일부 동적 에이전트의 생성 방법을 사용하면 심지어 운행은 지정된 에이전트 클래스의 실행 논리로 되어 시스템의 유연성을 크게 높일 수 있다.
테마 인터페이스:

public interface IDBQuery {
   String request();
 }
jdk 프록시 클래스:

public class JdbDbqueryHandler implements InvocationHandler{
  IDBQuery idbquery = null;
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    if(idbquery==null){
      idbquery = new DBQuery();
    }
    return idbquery.request();
  }
  public static IDBQuery createJdbProxy(){
    IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
        new Class[]{IDBQuery.class}, new JdbDbqueryHandler());
    System.out.println("JdbDbqueryHandler.createJdbProxy()");
    return jdkProxy;
  }

}

주 함수:

public class ProxyText {
  public static void main(String[] args) {
    IDBQuery idbQuery = JdbDbqueryHandler.createJdbProxy();
    System.out.println(idbQuery.request());
  }
}
또한 CGLIB와javassist 동적 에이전트를 사용하여 jdk 동적 에이전트와 유사하지만 jdk 동적 클래스의 생성 과정이 가장 빠르다. 이 내장된 difineclass () 방법은native 구현으로 정의되어 있기 때문에 성능이 다른 것보다 우수하다.프록시 클래스의 함수 호출에 있어 JDK의 동적 에이전트는 CGLIB와javassist 동적 에이전트보다 못하고,javassist 동적 에이전트의 성능 품질이 가장 나쁘며, 심지어는 JDK의 실현보다 못하다.실제 개발 응용에서 에이전트 클래스의 방법 호출 주파수는 에이전트 클래스의 실제 생성 주파수보다 훨씬 높기 때문에 동적 에이전트 방법 호출 성능은 성능의 관심사가 되어야 한다.JDK 동적 에이전트는 에이전트 클래스와 진짜 테마가 통일된 인터페이스를 실현하도록 강요합니다. CGLIB와javassist 동적 에이전트는 이런 요구가 없습니다.
자바에서 동적 에이전트의 실현은classloader의 사용과 관련된다. CGLIB를 예로 들어 동적 클래스의 불러오는 과정을 간략하게 설명한다.CGLIB를 사용하여 동적 에이전트를 생성하려면 먼저 Enhancer 클래스의 실례를 생성하고 에이전트 업무를 처리하는 데 사용할 리셋 클래스를 제정해야 한다.앙앙서.create() 메서드에서는 DefaultGeneratorStrategy가 사용됩니다.Generate () 방법은 프록시 클래스의 바이트 코드를 생성하고byte 그룹에 저장합니다.이어서 reflectUtils를 호출합니다.defineClass() 메서드, 반사를 통해 ClassLoader를 호출합니다.defineClass () 방법, 바이트 코드를classloader에 불러옵니다. 클래스의 불러오기를 완료합니다.마지막으로, reflectUtils를 통해.newInstance() 메서드는 반사를 통해 동적 클래스 실례를 생성하고 이 실례를 되돌려줍니다.다른 것은 이 과정의 세부 사항과 다르지만 생성 논리는 같다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기