Free Lines Arrow
본문 바로가기
Spring/Spring 고급

[Spring] JDK Proxy

by skahn1215 2023. 4. 18.
728x90
반응형

JDK Proxy

  • 인터페이스 기반으로 프록시를 동적으로 만든다.
  • 즉 인터페이스가 있어야 프록시를 만들수 있다.

 

JDK Proxy 예제

  • JDK 동적 프록시를 만들기 위해서는 InvoctionHandler 를 구현해주면 된다.
package java.lang.reflect;
public interface InvocationHandler {
   public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable;
}
  • proxy: 프록시 자신
  • method: 호출한 메소드
  • args: 메소드를 호출할때 전달한 인수

 

UserServiceInterface

  • 앞서 말했듯이 JDK proxy 는 인터페이스가 필요하다.
package com.example.exercise.aop.jdk;

public interface UserServiceInterface {
    public void save();
}

 

UserServiceImpl

package com.example.exercise.aop.jdk;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UserServiceImpl implements UserServiceInterface {
    @Override
    public void save() {
        log.info("save user info");
    }
}

 

LogInvocationHandler

package com.example.exercise.aop.jdk;

import lombok.extern.slf4j.Slf4j;

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

@Slf4j
public class LogInvocationHandler implements InvocationHandler {

    private final Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log.info("실행 전 로그");
        Object result = method.invoke(target, args);
        log.info("실행 후 로그");
        return result;
    }
}
  • Object target 은 외부에서 받는 타겟 클래스이다.
  • Object result = method.invoke(target, args);
    - 리플렉션을 이용하여 target 의 메소드를 수행한다.

 

 

TestCode

package com.example.exercise.aop;

import com.example.exercise.aop.jdk.LogInvocationHandler;
import com.example.exercise.aop.jdk.UserServiceInterface;
import com.example.exercise.aop.jdk.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Proxy;


@Slf4j
class LogInvocationHandlerTest {

    @Test
    void LogTest () {
        UserServiceInterface target = new UserServiceImpl();
        LogInvocationHandler logInvocationHandler = new LogInvocationHandler(target);
        UserServiceInterface proxy = (UserServiceInterface) Proxy.newProxyInstance(UserServiceInterface.class.getClassLoader(), new Class[]{UserServiceInterface.class}, logInvocationHandler);
        proxy.save();
        log.info("target class = {}", target.getClass());
        log.info("proxy class = {}", proxy.getClass());

    }
}
  • Proxy.newProxyInstance(classLoader, interface array, handler logic);
    - 클래스로더정보, 인터페이스, 핸들러 로직을 넣어주면 된다.
    - 그러면 해당 인터페이스로 동적 프록시를 생성하고 그결과를 반환한다.

 

결과

  • proxy class = 를 보면 jdk proxy 가 만들어진것을 확인 할 수 있다.
18:51:33.903 [Test worker] INFO com.example.exercise.aop.jdk.LogInvocationHandler -- 실행 전 로그
18:51:33.906 [Test worker] INFO com.example.exercise.aop.jdk.UserServiceImpl -- save user info
18:51:33.906 [Test worker] INFO com.example.exercise.aop.jdk.LogInvocationHandler -- 실행 후 로그
18:51:33.906 [Test worker] INFO com.example.exercise.aop.LogInvocationHandlerTest -- target class = class com.example.exercise.aop.jdk.UserServiceImpl
18:51:33.907 [Test worker] INFO com.example.exercise.aop.LogInvocationHandlerTest -- proxy class = class jdk.proxy3.$Proxy11

 

 

 

 

JDK 동작 과정

  • client 가 서비스를 직접 호출 하지 않고 
  • 프록시를 호출 하여 실제 서비스를 호출하게 된다.

 

 

 

 

참고:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B3%A0%EA%B8%89%ED%8E%B8/dashboard

 

스프링 핵심 원리 - 고급편 - 인프런 | 강의

스프링의 핵심 원리와 고급 기술들을 깊이있게 학습하고, 스프링을 자신있게 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

728x90
반응형

'Spring > Spring 고급' 카테고리의 다른 글

[Spring] Spring AOP 개념  (0) 2023.06.27
[Spring] AOP 개념  (0) 2023.06.15
[Spring] CGLIB  (0) 2023.04.18
[Spring] Proxy  (0) 2023.01.23

댓글