본문 바로가기

프록시

(5)
빈 후처리기, BeanPostProcessor 빈 후처리기 남아있는 문제 이전 포스팅에서 프록시 팩토리를 사용해서 스프링이 지원하는 프록시를 만들고 어드바이저로 부가기능을 생성해보았다. 스프링 빈에서 프록시 객체로 등록하기 위해서 해당 스프링 빈 대신에 프록시 객체를 넣고 프록시 객체 내부에서 부가기능과 함께 실제 객체를 호출하는 식으로 작성을 했다. 이렇게 할 때 문제는 복잡한 빈 등록 설정을 해줘야 한다는 것인데 빈 등록을 할 때 프록시 객체를 넘겨서 설정을 해주는 과정이 번거롭다. 게다가 빈을 컴포넌트 스캔으로 자동 등록할 때에는 이런식으로 수동으로 등록하기가 어렵다. 위와 같은 문제를 해결하기 위해 빈 후처리기를 사용한다. 빈 후처리기 (BeanPostProcessor) 객체를 스프링 빈 저장소에 등록하기 전에 조작을 할 수 있게 해주는 인터.. 더보기
스프링이 제공하는 프록시, 프록시 팩토리 spring 6. 스프링이 지원하는 프록시 프록시 팩토리 우리가 기존에 알아봤던 JDK 동적 프록시와 CGLIB을 사용한 프록시 구현(https://harrislee.tistory.com/95)은 각각 문제점이 있다. JDK 동적 프록시는 인터페이스가 있어야하고 CGLIB은 구체클래스가 있어야 구현이 가능하다. 인터페이스가 있을때는 JDK 동적 프록시를, 없을때는 CGLIB를 사용하도록 하려면 어떻게 해야할까? 또, 부가기능을 적용하기위해서 InvocationHandler, MethodInterceptor를 각각 만들었어야 했는데 이걸 공통으로 적용할 수는 없을까? 스프링에서는 동적프록시를 통합해주는 프록시 팩토리라는 기술을 제공한다. 프록시 팩토리가 알아서 인터페이스가 있을 때는 JDK 동적 프록시를,.. 더보기
Reflection, JDK 동적 프록시, CGLIB 리플렉션 자바 리플렉션은 우리가 컴파일 타임에 알 수 없는 정보들( 클래스, 인터페이스, 메서드, 필드 등)에 대해 런타임에 동적으로 접근하고 수정할 수 있게 해준다. 예제 리플렉션이 어떤 상황에서 필요한지를 살펴보자. 아래와 같이 Hello 라는 클래스가 있다. @Slf4j static class Hello{ public String callA(){ log.info("callA"); return "A"; } public String callB(){ log.info("callB"); return "B"; } } Hello 클래스의 메서드를 호출하기 전과 후에 log를 출력하고자 한다. 가장 쉽게 구현하는 방법은 호출하기 전과 후에 아래와 같이 로그를 남기는 것이다. @Test void Reflection.. 더보기
프록시, 프록시 패턴, 데코레이터 패턴 프록시 패턴과 데코레이터 패턴 Proxy 란? 클라이언트와 서버 관계는 컴퓨터 세상에서는 흔하게 볼 수 있는 구조다. 네트워크 상의 통신, 하나의 컴퓨터 내부의 프로세스간 통신, 심지어 애플리케이션 내부에서 객체간의 통신에서도 우리는 클라이언트 서버 관계를 쉽게 찾을 수 있다. 여기서는 객체간의 통신에서의 프록시에 대해 알아본다. 클라이언트는 서버에 필요한 것을 요청을 하고 서버는 그에 대한 처리를 하고 응답을 반환한다. 프록시는 이런 클라이언트와 서버 사이에서 요청에 대한 접근 제어, 부가기능 추가 등의 기능을 담당한다. 프록시는 컴퓨터 세상에 다양한 클라이언트 서버 관계들에서 존재할 수 있다. 그리고 클라이언트는 서버로 요청을 보냈지만 이를 처리하는 주체가 프록시인지 실제 서버인지 알 수는 없다. 프.. 더보기
JPA - 프록시 프록시 프록시 기초 em.find() vs em.getReference() em.find() : 데이터베이스를 통해서 실제 엔티티 객체 조회 em.getReference(): 데이터베이스 조회를 미루는 가짜(프록시) 엔티티 객체 조회 프록시 특징 실제 클래스를 상속 받아서 만들어짐 실제 클래스와 겉 모양이 같다. 사용하는 입장에서는 진짜 객체인지 프록시 객체인지 구분하지 않고 사용하면 됨(이론상) 프록시 객체는 실제 객체의 참조(target)를 보관 프록시 객체를 호출하면 프록시 객체는 실제 객체의 메소드 호출 프록시 객체의 초기화 Member member = em.getReference(Member.class, "id1"); member.getName(); 코드 실행 결과 Team team = new .. 더보기