이 기사에서는 java에 대한 관련 지식을 제공합니다. 동적 프록시는 프로그램 실행 시 결정되는 프록시 클래스와 대상 클래스 간의 관계를 의미합니다. 고객이 프록시 클래스를 통해 대상 객체를 호출하는 방법은 다음과 같습니다. 대상 클래스의 프록시 객체는 프로그램이 실행될 때 필요에 따라 동적으로 생성됩니다. 다음은 사례를 통해 Java 동적 프록시의 원리와 구현을 자세히 설명하겠습니다.
추천 학습: "java 비디오 튜토리얼"
"에이전트"라는 단어는 모두가 익숙하다고 생각합니다. 간단히 말하면 제조업체를 대신하여 상품을 판매하는 것을 의미하며 에이전트가 제조업체를 대신하여 판매합니다. 상품, 고객은 상품을 구매할 대리인을 찾습니다. 즉, 1) 고객과 제조업체의 관계는 눈에 보이지 않으며 고객은 제조업체가 그 배후에 있는지 알지 못합니다. 2) 에이전트는 고객을 "포지셔닝"하고 필요한 고객 그룹에 보다 정확하게 판매할 수 있습니다.
프록시 모드: 이 객체에 대한 액세스를 제어하기 위해 다른 객체에 프록시를 제공합니다. 즉, 클라이언트와 대상 객체 사이의 중개자로서 프록시 객체를 생성하는 것이 주요 목적입니다. 대상 개체를 강화합니다
프록시 패턴을 사용하면 일반적으로 다음 두 가지 이점이 있습니다.
1) 프록시 클래스의 구현을 숨길 수 있습니다
2) 코드를 수정하지 않고도 클라이언트와 프록시 클래스 간의 분리를 달성할 수 있습니다. 이 경우 몇 가지 추가 처리가 수행될 수 있습니다
소위 동적 프록시는 명확한 프록시 클래스를 선언하여 소스 개체에 액세스하는 것입니다. n개의 제품, N개의 에이전트가 필요하며 이는 비즈니스 개발에 도움이 되지 않습니다.
예: 마우스와 키보드라는 두 개의 인터페이스가 있고 각 인터페이스에는 구현 클래스가 있습니다
구현 클래스의 코드는 다음과 같습니다.
public class LogitechMouse implements Mouse{ @Override public void sell() { System.out.println("出售罗技鼠标"); } } public class HHKBKeyboard implements Keyboard{ @Override public void sell() { System.out.println("出售HHKB键盘"); } }
이제 우리가 해야 할 일은 에이전트를 call sell()
이전에 판매 전 이해에 대한 문장을 출력하고, 호출 후에는 A/S에 대한 문장을 출력합니다 sell()
前输出一句售前了解,调用后输出一句售后服务
那我们只需写两个代理类MouseProxy
和KeyboardProxy
public class MouseProxy implements Mouse { private Mouse mouse; public MouseProxy(Mouse mouse) { this.mouse = mouse; } @Override public void sell() { System.out.println("售前了解"); mouse.sell(); System.out.println("售后服务"); } } public class KeyboardProxy implements Keyboard{ private Keyboard keyboard; public KeyboardProxy(Keyboard keyboard) { this.keyboard = keyboard; } @Override public void sell() { System.out.println("售前了解"); keyboard.sell(); System.out.println("售后服务"); } }
最终执行为:
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); MouseProxy mouseProxy = new MouseProxy(logitechMouse); mouseProxy.sell(); Keyboard hhkbKeyboard = new HHKBKeyboard(); KeyboardProxy keyboardProxy = new KeyboardProxy(hhkbKeyboard); keyboardProxy.sell(); } }
输出:
售前了解
出售罗技鼠标
售后服务
售前了解
出售HHKB键盘
售后服务
静态代理的代码非常简单易懂,这种模式虽好,但是也有明显的缺点:
那么这个时候就可以使用动态代理来解决了
代理类在程序运行时创建代理的方式叫动态代理,也就是说代理类并不是在java代码中定义的,而是在运行的时候动态生成的
JDK从1.3版本就开始支持动态代理类的创建。主要核心类只有2个:java.lang.reflect.Proxy
和java.lang.reflect.InvocationHandler
MouseProxy
2개만 작성하면 됩니다. > 및 KeyboardProxy
public class JDKProxy implements InvocationHandler { private Object object; public JDKProxy(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, args); System.out.println("售后服务"); return invoke; } }최종 실행은 다음과 같습니다.
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); JDKProxy jdkProxy = new JDKProxy(logitechMouse); Mouse mouse= (Mouse)Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{Mouse.class}, jdkProxy); mouse.sell(); HHKBKeyboard hhkbKeyboard = new HHKBKeyboard(); JDKProxy jdkProxy1 = new JDKProxy(hhkbKeyboard); Keyboard keyboard = (Keyboard)Proxy.newProxyInstance(jdkProxy1.getClass().getClassLoader(), new Class[]{Keyboard.class}, jdkProxy1); keyboard.sell(); } }
출력:정적 프록시의 코드는 매우 간단하고 이해하기 쉽습니다. 명백한 단점:
사전 판매 이해
로지텍 마우스 판매
애프터 서비스사전 판매 이해
HHKB 키보드 판매
애프터 서비스
많은 수의 중복 프록시 클래스가 있으며 여기에는 인터페이스가 두 개뿐입니다. n개의 인터페이스가 있는 경우 n개의 프록시 클래스를 정의해야 합니다.
인터페이스가 변경되면 프록시 클래스와 프록시 클래스를 모두 변경해야 합니다.
그러면 이때 동적 프록시를 사용하여 문제를 해결할 수 있습니다
동적 프록시
프로그램 실행 시 프록시 클래스가 프록시를 생성하는 방식을 동적 프록시라고 하는데, 이는 프록시 클래스가 정의되어 있지 않다는 의미입니다. Java 코드이지만
JDK는 버전 1.3부터 동적 프록시 클래스 생성을 지원했습니다. 주요 핵심 클래스는 java.lang.reflect.Proxy
와 java.lang.reflect.InvocationHandler
두 개뿐입니다.
위의 예에서도 다음과 같이 JDK 동적 프록시를 사용하세요. :
public class CGLIBProcy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); private Object object; public CGLIBProcy(Object object) { this.object = object; } public Object getProxy(){ //设置需要创建子类的类 enhancer.setSuperclass(object.getClass()); enhancer.setCallback(this); //创建代理对象 return enhancer.create(); } // o: cglib 动态生成的代理类的实例 // method:实体类所调用的都被代理的方法的引用 // objects 参数列表 // methodProxy:生成的代理类对方法的代理引用 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("售前了解"); Object invoke = method.invoke(object, objects); System.out.println("售后处理"); return invoke; } }
public class Test { public static void main(String[] args) { Mouse logitechMouse = new LogitechMouse(); CGLIBProcy cglibProcy = new CGLIBProcy(logitechMouse); Mouse proxy = (Mouse)cglibProcy.getProxy(); proxy.sell(); cglibProcy = new CGLIBProcy(new HHKBKeyboard()); Keyboard keyboard = (Keyboard)cglibProcy.getProxy(); keyboard.sell(); } }🎜인터페이스가 아무리 많아도 프록시 클래스는 하나만 필요하다는 것을 알 수 있습니다. 🎜🎜CGLIB 동적 프록시🎜🎜에이전트 클래스: 🎜rrreee🎜실행 코드: 🎜rrreee🎜JDK 프록시와 CGLIB 프록시의 차이점🎜🎜🎜JDK 동적 프록시는 인터페이스를 구현합니다. CGLIB 동적 상속 아이디어🎜🎜JDK 동적 프록시(대상이 객체에 인터페이스가 있음)실행 효율성이 CIGLIB🎜🎜보다 높습니다. 객체에 인터페이스 구현이 있으면 JDK 프록시를 선택하세요. 인터페이스 구현이 없으면 CGILB 프록시를 선택하세요🎜🎜🎜권장 학습: "🎜java 비디오 튜토리얼🎜" 🎜
위 내용은 Java 동적 프록시에 대한 완전한 숙달의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!