java프록시란 무엇인가요?
Proxy는 대상 개체에 액세스하는 또 다른 방법, 즉 프록시 개체를 통해 대상 개체에 액세스하는 방법을 제공하는 디자인 패턴입니다. 대상 개체를 수정하지 않고도 대상 개체의 기능을 확장할 수 있습니다.
에이전트의 역할: 코드 중복을 줄입니다.
프록시 모드의 구현은 정적 구현과 동적 구현의 두 가지 범주로 나뉩니다. 동적 구현은 구현 방법에 따라 구분됩니다: jdk 동적 구현, cglib 동적 구현
Java의 세 가지 프록시 모드
달성하고 싶습니다. 위의 요구 사항을 충족하는 세 가지 방법이 있습니다. 이 부분에서는 세 가지 모드에 대한 코드를 작성하는 방법만 살펴보고 구현 원칙을 먼저 다루지 않습니다.
1. 정적 프록시
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } } /** * 代理对象和目标对象实现相同的接口 */ public class SingerProxy implements ISinger{ // 接收目标对象,以便调用sing方法 private ISinger target; public UserDaoProxy(ISinger target){ this.target=target; } // 对目标对象的sing方法进行功能扩展 public void sing() { System.out.println("向观众问好"); target.sing(); System.out.println("谢谢大家"); } }
Test
/** * 测试类 */ public class Test { public static void main(String[] args) { //目标对象 ISinger target = new Singer(); //代理对象 ISinger proxy = new SingerProxy(target); //执行的是代理的方法 proxy.sing(); } }
장점: 대상 객체의 기능을 수정하지 않고 대상 기능을 확장합니다.
단점: 이 구현 방법은 매우 직관적이고 간단하지만 단점은 프록시 객체를 반드시 사용해야 한다는 것입니다. 인터페이스 계층이 변경되면 프록시 객체의 코드도 유지되어야 합니다. 프록시 객체를 런타임에 동적으로 작성할 수 있다면 프록시 클래스 코드의 수를 크게 줄일 수 있을 뿐만 아니라 지속적인 유지 관리 문제도 줄일 수 있지만 런타임 효율성에는 확실히 영향을 미칩니다. 이 방법은 다음 동적 프록시입니다.
2. JDK 프록시
정적 프록시의 전제는 여전히 Singer 객체를 확장합니다
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } }
이번에는 Java의 하위 계층이 구현 세부 사항을 캡슐화하므로 직접 테스트합니다. 나중에 자세히 설명) 코드도 기본적으로 매우 간단합니다.
Proxy 클래스의 정적 메소드인 newProxyInstance를 호출하면 됩니다. 이 메소드는 프록시 클래스 객체를 반환합니다
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
수신된 세 가지 매개변수는 다음과 같습니다.
●ClassLoader 로더: 클래스 로더를 사용할 현재 대상 객체, 쓰기 메소드를 지정합니다. 고정됨
● 클래스>[] 인터페이스: 대상 객체가 구현하는 인터페이스 유형, 작성 방법이 고정됨
● InvocationHandler h: 이벤트 처리 인터페이스, 구현 클래스가 전달되어야 함, 일반적으로 익명 내부 클래스를 직접 사용
테스트 코드
public class Test{ public static void main(String[] args) { Singer target = new Singer(); ISinger proxy = (ISinger) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("向观众问好"); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }); proxy.sing(); } }
장점 : 대상 객체의 로직을 변경하지 않고 동적으로 확장을 구현함
단점 : 정적 프록시와 JDK 프록시에는 공통적인 단점, 즉 대상 객체가 있다는 것을 알 수 있습니다. 하나 이상의 인터페이스를 구현해야 합니다. 그렇지 않으면 동적 프록시를 구현할 수 없습니다.
3. Cglib 에이전트
전제조건:
● Spring의 핵심 패키지에는 이미 Cglib 기능이 포함되어 있으므로 spring-core-3.2.5.jar을 직접 도입할 수도 있습니다. 대상 클래스는 final일 수 없습니다
●대상 개체의 메서드가 final/static이면 가로채지 않습니다. 즉, 대상 개체의 추가 비즈니스 메서드가 실행되지 않습니다
/** * 目标对象,没有实现任何接口 */ public class Singer{ public void sing() { System.out.println("唱一首歌"); } }
/** * Cglib子类代理工厂 */ public class ProxyFactory implements MethodInterceptor{ // 维护目标对象 private Object target; public ProxyFactory(Object target) { this.target = target; } // 给目标对象创建一个代理对象 public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("向观众问好"); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }
여기 코드도 매우 고정, 노란색 부분만 직접 작성해야 합니다.
test
/** * 测试类 */ public class Test{ public static void main(String[] args){ //目标对象 Singer target = new Singer(); //代理对象 Singer proxy = (Singer)new ProxyFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.sing(); } }
장점: 대상 개체의 논리를 변경하지 않고 확장을 동적으로 구현합니다.
단점: 대상에서 인터페이스를 구현해야 합니다. 그렇지 않으면 동적 프록시를 구현할 수 없습니다.
요약: 세 가지 프록시 모드에는 각각 고유한 장점, 단점 및 해당 응답이 있습니다. 적용 범위는 주로 대상 개체가 인터페이스를 구현하는지 여부에 따라 다릅니다. Spring 프레임워크에서 선택한 프록시 모드를 예로 들어보세요
Spring의 AOP 프로그래밍에서:컨테이너에 추가된 대상 개체에 구현 인터페이스가 있으면 JDK 프록시를 사용하세요.대상 개체가 인터페이스를 구현하지 않으면 Cglib를 사용하세요. 프록시
위 내용은 자바에서 프록시란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!