You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
실무에서는 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 있고 없는 경우도 있다. 그리고 스프링 빈을 수동으로 직접 등록하는 경우도 있고 컴포넌트 스캔으로 자동으로 등록하는 경우도 잇다. 이런 다양한 케이스에 프록시를 어떻게 적용하는지 알아보기 위해 다양한 예제를 준비
v1 - 인터페이스와 구현 클래스 : 스프링 빈으로 수동 등록
지금까지 보여왔던 Controller, Service , Repository 에 인터페이스를 도입하고 스츠링 빈으로 수동 등록해본다.
packagehello.proxy.app.v1;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestParam;
importorg.springframework.web.bind.annotation.ResponseBody;
@RequestMapping//스프링은 @Controller 또는 @RequestMapping이 있어야 스프링 컨트롤러로 인식@ResponseBodypublicinterfaceOrderControllerV1 {
@GetMapping("/v1/request")
Stringrequest(@RequestParam("itemId") StringitemId);
@GetMapping("/v1/no-log")
StringnoLog();
}
@RequestMapping : Spring MVC 는 @controller 또는 @RequestMapping 애노테이션이 타입(인터페이스나 클래스)에 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야 HTTP URL이 매핑되고 동작한다. 이 애노테이션은 인터페이스에 사용해도 된다.
@responsebody : HTTP 메세지 컨버터를 사용해서 응답한다. 이 애노테이션은 인터페이스에 사용해도 된다.
코드를 보면 request() , noLog() 두가지 메서드가 있다. request() 는 LogTrace를 적용할 대상이고 noLog()는 단순히 LogTrace를 적용하지 않을 대상이다.
@Import(AppV1Config.class) : 클래스를 스프링 빈으로 등록한다. 여기서는 AppV1Config.class를 스프링 빈으로 등록한다. 일반적으로 @configuration과 같은 설정 파일을 등록할때 사용하지만 스프링 빈을 등록할때도 사용할 수 잇따.
@SpringBootApplication(scanBasePackages = "hello.proxy.app") : @componentscan 의 기능과 같다. 컴포넌트 스캔을 시작할 위치를 지정한다. 이값을 설정하면 해당 패키지와 그 하위 패키지를 컴포넌트 스캔한다. 이 값을 사용하지 않으면 ProxyApplication 이 있는 패키지와 그 하위 패키지를 스캔하낟. 참고로 v3 에서 지금 설정한 컴포넌트 스캔 기능을 사용한다.
실행 : localhost:8080/v1/request?itemId=hello
성공해서 ok 떠야함
주의
강의에서는 @configuration을 사용한 수동 빈 등록 설정을 hello.proxy.config 위치에 두고 점진적으로 변경할 예정이다. 지금은 AppV1Config.class 를 @import를 사용해서 설정하지만 이후에 다른 것을 설정한다는 이야기이다.
@configuration은 내부에 @component애노테이션을 포함하고 있어서 컴포넌트 스캔의 대상이 된다. 따라서 컴포넌트 스캔에 의해 hello.proxy.config 위치의 설정 파일들이 스프링 빈으로 자동 등록 되지 않도록 컴포넌트 스캔의 시작위치는 scanBasePackages=hello.proxy.app으로 설정해야 한다.
@RequestMapping : 스프링 MVC 는 @controller 또는 @RequestMapping 애노테이션이 타입에 잇어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL 이 매핑되고 동작한다. 그런데 여기서는 @controller를 사용하지 않고 @RequesetMapping 애노테이션을 사용했다. 그 이유는 @controller 를 사용하면 자동 컴포넌트 스캔의 대상이 대상이 되기 때문이다. 여기서는 컴포넌트 스캔을 통한 자동 빈 등록이 아니라 수동 빈 등록을 하는 것이 목표다. 따라서 컴포넌트 스캔과 관계없는 @RequestMapping를 타입에 사용했다.
ProxyApplication 에서 @SpringBootApplication(scanBasePackages = “hello.proxy.app”) 를 사용했고 각각 @RestController , @service , @repository 애노테이션을 가지고 있기 때문에 컴포넌트 스캔의 대상이 된다.
HTTP 요청 단위로 특정 ID 를 남겨서 어떤 HTTP 요청에서 시작된 것인지 명확하게 구분이 가능해야 함
트랜잭션 ID (DB 트랜잭션 X)
예시
하지만
이 요구사항을 만족하기 위해서 기존 코드를 많이 수정해야 한다. 코드 수정을 최소화 하기 위해 템플릿 메서드 패턴과 콜백 패턴도 사용했지만 결과적으로 로그를 남기고 싶은 클래스가 수백개라면 수백개의 클래스를 모두 고쳐야한다. 로그를 남길 때 기존 원본 코드를 변경해야 한다는 사실 그 자체가 개발자에게는 가장 큰 문제로 남는다.
기존 요구사항에 다음 요구사항이 추가되었다.
요구사항 추가
원본 코드를 전혀 수정하지 않고 로그 추적기를 적용해라
특정 메서드는 로그를 출력하지 않는 기능
보안상 일부는 로그를 출력하면 안된다.
다음과 같은 다양한 케이스에 적용할 수 있어야 한다.
v1 : 인터페이스가 있는 구현 클래스에 적용
v2 : 인터페이스가 없는 구체 클래스에 적용
v3 : 컴포넌트 스캔 대상에 기능 적용
가장 어려운 문제는 원본 코드를 전혀 수정하지 않고 로그 추적기를 도입하는 것이다. 이 문제를 해결하려면 Proxy 개념을 먼저 이해해야 한다.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
프로젝트 생성
proxy -start : build.gradle
예제프로젝트 만들기 v1
예제 3가지 상황
실무에서는 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 있고 없는 경우도 있다. 그리고 스프링 빈을 수동으로 직접 등록하는 경우도 있고 컴포넌트 스캔으로 자동으로 등록하는 경우도 잇다. 이런 다양한 케이스에 프록시를 어떻게 적용하는지 알아보기 위해 다양한 예제를 준비
v1 - 인터페이스와 구현 클래스 : 스프링 빈으로 수동 등록
지금까지 보여왔던
Controller,Service,Repository에 인터페이스를 도입하고 스츠링 빈으로 수동 등록해본다.Service
OrderServiceV1OrderServiceV1ImplRepository
OrderRepositoryV1OrderRepositoryV1ImplController
OrderControllerV1@RequestMapping: Spring MVC 는 @controller 또는 @RequestMapping 애노테이션이 타입(인터페이스나 클래스)에 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야 HTTP URL이 매핑되고 동작한다. 이 애노테이션은 인터페이스에 사용해도 된다.request(),noLog()두가지 메서드가 있다.request()는 LogTrace를 적용할 대상이고noLog()는 단순히 LogTrace를 적용하지 않을 대상이다.OrderControllerV1ImplAppV1Config
ProxyApplication
@Import(AppV1Config.class): 클래스를 스프링 빈으로 등록한다. 여기서는AppV1Config.class를 스프링 빈으로 등록한다. 일반적으로 @configuration과 같은 설정 파일을 등록할때 사용하지만 스프링 빈을 등록할때도 사용할 수 잇따.@SpringBootApplication(scanBasePackages = "hello.proxy.app"): @componentscan 의 기능과 같다. 컴포넌트 스캔을 시작할 위치를 지정한다. 이값을 설정하면 해당 패키지와 그 하위 패키지를 컴포넌트 스캔한다. 이 값을 사용하지 않으면ProxyApplication이 있는 패키지와 그 하위 패키지를 스캔하낟. 참고로 v3 에서 지금 설정한 컴포넌트 스캔 기능을 사용한다.실행 : localhost:8080/v1/request?itemId=hello
성공해서 ok 떠야함
주의
강의에서는 @configuration을 사용한 수동 빈 등록 설정을 hello.proxy.config 위치에 두고 점진적으로 변경할 예정이다. 지금은 AppV1Config.class 를 @import를 사용해서 설정하지만 이후에 다른 것을 설정한다는 이야기이다.
@configuration은 내부에 @component애노테이션을 포함하고 있어서 컴포넌트 스캔의 대상이 된다. 따라서 컴포넌트 스캔에 의해 hello.proxy.config 위치의 설정 파일들이 스프링 빈으로 자동 등록 되지 않도록 컴포넌트 스캔의 시작위치는
scanBasePackages=hello.proxy.app으로 설정해야 한다.예제 프로젝트 만들기 V2
이번에는 인터페이스가 없는 걸로 만들기
@RequestMapping : 스프링 MVC 는 @controller 또는 @RequestMapping 애노테이션이 타입에 잇어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL 이 매핑되고 동작한다. 그런데 여기서는 @controller를 사용하지 않고 @RequesetMapping 애노테이션을 사용했다. 그 이유는 @controller 를 사용하면 자동 컴포넌트 스캔의 대상이 대상이 되기 때문이다. 여기서는 컴포넌트 스캔을 통한 자동 빈 등록이 아니라 수동 빈 등록을 하는 것이 목표다. 따라서 컴포넌트 스캔과 관계없는 @RequestMapping를 타입에 사용했다.
OrderRepositoryV2
예제 프로젝트 만들기 V3
컴포넌트 스캔으로 스프링 빈을 자동 등록해보자.
Service
Repository
Controller
ProxyApplication에서@SpringBootApplication(scanBasePackages = “hello.proxy.app”)를 사용했고 각각 @RestController , @service , @repository 애노테이션을 가지고 있기 때문에 컴포넌트 스캔의 대상이 된다.실행
http://localhost:8080/v3/request?itemId=hello
결과
웹브라우저 화면 “OK”
요구사항 추가
지금까지 로그추적기를 만들어서 기존 요구사항을 모두 만족했다.
기존 요구사항
예시
하지만
이 요구사항을 만족하기 위해서 기존 코드를 많이 수정해야 한다. 코드 수정을 최소화 하기 위해 템플릿 메서드 패턴과 콜백 패턴도 사용했지만 결과적으로 로그를 남기고 싶은 클래스가 수백개라면 수백개의 클래스를 모두 고쳐야한다. 로그를 남길 때 기존 원본 코드를 변경해야 한다는 사실 그 자체가 개발자에게는 가장 큰 문제로 남는다.
기존 요구사항에 다음 요구사항이 추가되었다.
요구사항 추가
가장 어려운 문제는 원본 코드를 전혀 수정하지 않고 로그 추적기를 도입하는 것이다. 이 문제를 해결하려면 Proxy 개념을 먼저 이해해야 한다.
All reactions