자바 리플렉션-동적 프록시

자바 리플렉션을 사용하여 런타임에 인터페이스의 동적 구현을 만듭니다. 클래스java.lang.reflect.Proxy을 사용하여 이렇게 합니다. 이 클래스의 이름은 이러한 동적 인터페이스 구현을 동적 프록시라고 부르는 이유입니다. 동적 프록시는 데이터베이스 연결 및 트랜잭션 관리,단위 테스트를위한 동적 모의 객체 및 기타 다른 목적으로 사용될 수 있습니다.

프록시 만들기

Proxy.newProxyInstance()방법을 사용하여 동적 프록시를 만듭니다. newProxyInstance()메서드는 3 개의 매개 변수를 사용합니다:

  1. 동적 프록시 클래스를”로드”하는ClassLoader입니다.
  2. 구현할 인터페이스 배열입니다.
  3. InvocationHandler프록시에서 모든 메서드 호출을 전달합니다.

이 코드를 실행 한 후proxy변수에MyInterface인터페이스의 동적 구현이 포함되어 있습니다. 프록시에 대한 모든 호출은 일반InvocationHandler인터페이스의handler구현으로 전달됩니다. 호출 핸들의 다음 섹션 내가 덮여있다.

호출 핸들의

앞에서 설명한 대로InvocationHandler구현을Proxy.newProxyInstance()메서드에 전달해야 합니다. 동적 프록시에 대한 모든 메서드 호출은 이InvocationHandler구현으로 전달됩니다. 다음은InvocationHandler인터페이스의 모습입니다:

public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object args) throws Throwable;}

다음은 구현 예제입니다:

public class MyInvocationHandler implements InvocationHandler{ public Object invoke(Object proxy, Method method, Object args) throws Throwable { //do something "dynamic" }}

invoke()메서드에 전달된proxy매개 변수는 인터페이스를 구현하는 동적 프록시 개체입니다. 대부분의 경우 이 개체가 필요하지 않습니다.

invoke()메서드에 전달된Method개체는 동적 프록시가 구현하는 인터페이스에서 호출된 메서드를 나타냅니다. Method개체에서 메서드 이름,매개 변수 유형,반환 유형 등을 얻을 수 있습니다. 자세한 내용은 메서드에 대한 텍스트를 참조하십시오.

Object args배열에는 구현된 인터페이스의 메서드가 호출될 때 프록시에 전달된 매개 변수 값이 포함되어 있습니다. 참고:구현 된 인터페이스의 프리미티브(정수,긴 등)는 객체 대응 물(정수,긴 등)로 래핑됩니다.).

알려진 사용 사례

동적 프록시는 적어도 다음 용도로 사용되는 것으로 알려져 있습니다:

  • 데이터베이스 연결 및 트랜잭션 관리
  • 단위 테스트를 위한 동적 모의 객체
  • 사용자 정의 팩토리 인터페이스에 대한 컨테이너의 적응
  • 데이터베이스 연결 및 트랜잭션 관리

    스프링 프레임워크에는 트랜잭션을 시작하고 커밋/롤백할 수 있는 트랜잭션 프록시가 있습니다. 이 작동 방식은 고급 연결 및 트랜잭션 경계 및 전파 텍스트에 더 자세히 설명되어 있으므로 간단히 설명하겠습니다.

    단위 테스트를 위한 동적 모의 객체

    나비 테스트 도구는 동적 프록시를 사용하여 단위 테스트를 위한 동적 스텁,모의 및 프록시를 구현합니다. 다른 클래스를 사용하는 클래스를 테스트 할 때 비(인터페이스 정말),당신은 모의 구현을 전달할 수 있습니다 비 에 대신 실제 비. 이제 모든 메서드 호출이 기록되고 모의 메서드가 반환할 반환 값을 설정할 수 있습니다.예를 들어,다오를 테스트하면 데이터베이스 연결을 모의 래핑할 수 있습니다. 다오는 차이를 볼 수 없습니다,그리고 다오는 데이터베이스에 대한 모든 호출을 전달 모의 이후 평소와 같이 데이터베이스에 데이터를 읽기/쓰기 할 수 있습니다. 다오가 제대로 연결을 사용하는 경우 그러나 지금 당신은 모의를 통해 확인할 수 있습니다,예를 들어connection.close()가 호출되는 경우(또는 호출되지 않음),당신이 예상하는 경우. 이것은 일반적으로 다오의 반환 값에서 확인할 수 없습니다.종속성 주입 컨테이너 버터플라이 컨테이너는 전체 컨테이너를 생산된 콩에 주입할 수 있는 강력한 기능을 가지고 있습니다. 그러나 컨테이너 인터페이스에 대한 종속성을 원하지 않기 때문에 컨테이너는 디자인의 사용자 지정 팩토리 인터페이스에 적응할 수 있습니다. 당신은 인터페이스가 필요합니다. 구현이 없습니다. 따라서 공장 인터페이스와 클래스는 다음과 같이 보일 수 있습니다:

    public interface IMyFactory { Bean bean1(); Person person(); ...}

    MyAction클래스가 컨테이너에 의해 생성자에 주입된IMyFactory인스턴스의 메서드를 호출하면 메서드 호출은IContainer.instance()메서드에 대한 호출로 변환됩니다. 그런 식으로 객체는 생성시 종속성을 자체 주입하기보다는 런타임에 버터 플라이 컨테이너를 팩토리로 사용할 수 있습니다. 그리고 이것은 나비 컨테이너 특정 인터페이스에 대한 종속성이 없습니다.

    스프링 프레임워크는 빈이 일부 인터페이스를 구현한다면 주어진 빈에 대한 메소드 호출을 가로채는 것을 가능하게 한다. 스프링 프레임워크는 빈을 동적 프록시로 래핑합니다. 그런 다음 빈에 대한 모든 호출이 프록시에 의해 차단됩니다. 프록시는 메서드 호출을 래핑 된 빈에 위임하기 전,대신 또는 후에 다른 개체에서 다른 메서드를 호출하도록 결정할 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다.