728x90

JDK 동적 프록시 (JDK Dynamic Proxy)란?

JDK 동적 프록시는 자바의 java.lang.reflect.Proxy 클래스를 이용해서 런타임에 동적으로 프록시 객체를 생성하는 기술이야.

📌 즉, 컴파일 시점이 아니라 실행 시점에서 인터페이스를 기반으로 프록시 객체를 만들어주는 기능!
✔️ AOP에서 메서드 실행 전/후에 부가 기능을 추가할 때 주로 사용됨.
✔️ Spring AOP에서 기본적으로 사용하는 프록시 방식!

 


📌 왜 JDK 동적 프록시를 사용할까?

"코드 수정 없이, 실행 중에 특정 객체의 동작을 변경할 수 있기 때문!"

예를 들어,

  • 로깅(logging)
  • 트랜잭션 관리(transaction)
  • 성능 모니터링(performance monitoring)

같은 기능을 비즈니스 로직과 분리해서 적용할 수 있어.

 

 


📌 JDK 동적 프록시의 특징

인터페이스 기반 → 프록시를 만들기 위해 반드시 인터페이스가 필요함
InvocationHandler 인터페이스 사용 → 프록시가 호출될 때 실행될 동작을 정의
Spring AOP에서 기본적으로 사용 → Spring AOP는 기본적으로 JDK 동적 프록시를 활용해서 AOP를 구현

 

 


📌 JDK 동적 프록시 예제

1️⃣ 먼저, 실제 서비스 인터페이스와 구현 클래스 만들기

// 1. 서비스 인터페이스
public interface Service {
    void doSomething();
}

// 2. 실제 서비스 구현 클래스
public class RealService implements Service {
    @Override
    public void doSomething() {
        System.out.println("실제 서비스 실행 중...");
    }
}

✔️ RealService는 Service 인터페이스를 구현하는 실제 서비스 클래스야.

 


2️⃣ JDK 동적 프록시 구현 (InvocationHandler 사용)

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

// 동적 프록시를 위한 InvocationHandler 구현
public class LoggingInvocationHandler implements InvocationHandler {
    private final Object target; // 실제 객체

    public LoggingInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 부가 기능 (메서드 실행 전)
        System.out.println("[LOG] 실행 전: " + method.getName());

        // 실제 메서드 실행
        Object result = method.invoke(target, args);

        // 부가 기능 (메서드 실행 후)
        System.out.println("[LOG] 실행 후: " + method.getName());

        return result;
    }
}

✔️ InvocationHandler를 구현해서 메서드 호출 전후로 로깅 기능을 추가했어.
✔️ method.invoke(target, args); → 실제 객체의 메서드를 실행하는 부분!

 


3️⃣ JDK 동적 프록시 생성하기

import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        // 실제 객체 생성
        RealService realService = new RealService();

        // 동적 프록시 생성
        Service proxyInstance = (Service) Proxy.newProxyInstance(
                realService.getClass().getClassLoader(), // 클래스 로더
                new Class[]{Service.class}, // 프록시가 구현할 인터페이스
                new LoggingInvocationHandler(realService) // InvocationHandler 구현체
        );

        // 프록시 객체로 메서드 호출
        proxyInstance.doSomething();
    }
}

✅ Proxy.newProxyInstance()를 사용하여 실행 시점에 프록시 객체를 동적으로 생성했어!
✅ proxyInstance.doSomething();을 호출하면 프록시 객체가 대신 실행하고, LoggingInvocationHandler에서 로깅을 추가함.

 

 


📌 실행 결과

[LOG] 실행 전: doSomething
실제 서비스 실행 중...
[LOG] 실행 후: doSomething

실제 서비스 로직을 건드리지 않고 부가 기능(로깅)을 추가할 수 있었음!

 

 


📌 정리

🔹 JDK 동적 프록시는 실행 중에 프록시 객체를 동적으로 생성하는 기술
🔹 인터페이스 기반으로 동작하며, InvocationHandler를 사용
🔹 Spring AOP에서 기본적으로 프록시 기반 AOP를 구현할 때 사용
🔹 부가 기능(로깅, 트랜잭션, 보안 등)을 추가할 때 유용

728x90

'프로그래밍 > Spring' 카테고리의 다른 글

Spring View란? +DTO,VO  (0) 2025.03.31
Spring Controller란?  (0) 2025.03.28
Proxy Pattern(프록시 패턴)  (0) 2025.03.27
Spring셋팅 하기  (0) 2025.03.27
Spring에서 빈(Bean)의 종류  (0) 2025.03.26