프록시 모드는 프록시 개체를 사용하여 사용자 요청을 완료하고 사용자가 실제 개체에 액세스하지 못하도록 보호합니다.
프록시 모드에는 다양한 용도가 있습니다. 예를 들어 보안상의 이유로 클라이언트가 실제 개체에 직접 액세스하지 못하도록 보호해야 하거나 원격 호출에서 기술 세부 사항을 처리하려면 프록시 개체를 사용해야 합니다. 원격 방법에서 또는 시스템을 개선하기 위해 지연 로딩의 목적을 달성하기 위해 실제 객체가 캡슐화됩니다.
시스템 시작 시 리소스를 가장 많이 소모하는 방식을 프록시 모드로 분리하면 시스템 시작 속도를 높이고 사용자의 대기 시간을 줄일 수 있습니다. 사용자가 실제로 쿼리를 수행할 때 프록시 클래스는 사용자의 요청을 완료하기 위해 실제 클래스를 로드합니다. 이는 지연 로딩을 달성하기 위해 프록시 모드를 사용하는 목적입니다.
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()); } }
정적 프록시 프록시 클래스는 공통 인터페이스를 구현하는 실제 클래스입니다. 및 프록시 클래스는 실제 클래스 객체를 참조하며 시간이 많이 걸리는 작업은 프록시 클래스 메서드에서 구현됩니다.
동적 프록시:
동적 프록시는 프록시 클래스를 동적으로 생성하는 런타임입니다. 즉, 프록시 클래스의 바이트코드가 생성되어 런타임 시 현재 클래스로더에 로드됩니다. 정적 프록시에 비해 동적 프록시는 실제 주의를 끌기 위해 완전히 동일한 캡슐화 클래스를 캡슐화할 필요가 없습니다. 주제 인터페이스가 많으면 인터페이스마다 프록시 메소드를 작성하는 것이 매우 귀찮습니다. 에이전트 클래스와 에이전트 클래스를 변경해야 하는데 이는 시스템 유지 관리에 도움이 되지 않습니다. 둘째, 일부 동적 에이전트 생성 방법을 사용하면 런타임 시 에이전트 클래스의 실행 논리를 지정할 수도 있으므로 시스템의 유연성이 크게 향상됩니다.
테마 인터페이스:
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()); } }
또한 jdk 동적 프록시와 유사한 CGLIB 및 javassist 동적 프록시를 사용할 수도 있지만, 이 내장 구현의 diffineclass() 메소드가 있기 때문에 jdk 동적 클래스 생성 프로세스가 가장 빠릅니다. 기본 구현으로 정의되므로 성능이 다른 것보다 좋습니다. 프록시 클래스의 함수 호출 측면에서 JDK의 동적 프록시는 CGLIB 및 javassist 동적 프록시만큼 좋지 않으며 javassist 동적 프록시는 성능 품질이 최악이며 JDK 구현보다 열등합니다. 실제 개발 응용 프로그램에서는 프록시 클래스의 메서드 호출 빈도가 프록시 클래스의 실제 생성 빈도보다 훨씬 높으므로 동적 프록시의 메서드 호출 성능이 성능 문제가 되어야 합니다. JDK 동적 프록시는 프록시 클래스와 실제 테마가 통합 인터페이스를 구현하도록 강제하며 javassist 동적 프록시에는 이러한 요구 사항이 없습니다.
Java에서 동적 프록시 구현에는 클래스로더를 사용하는 작업이 포함됩니다. CGLIB를 예로 들어 동적 클래스 로딩 프로세스를 간략하게 설명합니다. CGLIB를 사용하여 동적 프록시를 생성하려면 먼저 Enhancer 클래스의 인스턴스를 생성하고 프록시 서비스를 처리하기 위한 콜백 클래스를 공식화해야 합니다. Enhancer.create() 메서드에서는 DefaultGeneratorStrategy.Generate() 메서드를 사용하여 프록시 클래스의 바이트코드를 생성하고 이를 바이트 배열에 저장합니다. 그런 다음 ReflectUtils.defineClass() 메서드를 호출하고 리플렉션을 통해 ClassLoader.defineClass() 메서드를 호출하여 클래스 로더에 바이트코드를 로드하여 클래스 로드를 완료합니다. 마지막으로 ReflectUtils.newInstance() 메소드를 통해 리플렉션을 통해 동적 클래스 인스턴스를 생성하고 해당 인스턴스를 반환합니다. 프로세스의 다른 세부 사항은 다르지만 생성 논리는 동일합니다.
위 내용은 이 글의 전체 내용이므로, 모든 분들의 공부에 도움이 되었으면 좋겠습니다.
자바 디자인 최적화의 프록시 모드에 관한 더 많은 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!