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
이전 프로젝트를 일부 수정해서 proxy-start 라는 프로젝트에 넣어두었다. 프로젝트 설정 순서
proxy-start 의 폴더 이름을 proxy
프로젝트 임포트
예제 프로젝트 만들기 v1
다양한 상황에서 프록시 사용법을 이해하기 위해 다음과 같은 기준으로 기본 예제 프로젝트를 만들어보자.
예제는 크게 3가지 상황으로 만든다.
v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
v2 - 인터페이스 없는 구체 클래스 - 스프링 빈으로 수동 등록
v3 - 컴포넌트 스캔으로 스프링 빈 자동 등록
실무에서는 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 있고 없는 경우도 있다. 그리고 스프링 빈을 수동으로 직접 등록하는 경우도 있고, 컴포넌트 스캔으로 자동으로 등록하는 경우도 있다. 이런 다양한 케이스에 프록시를 어떻게 적용하는지 알아보기 위해 다양한 예제를 준비해보자.
v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
지금까지 보아왔던 Controller , Service , Repository 에 인터페이스를 도입하고, 스프링 빈으로 수동 등록해 보자.
@RequestMapping// 스프링은 @Controller 또는 @RequestMapping 이 있어야 스프링 컨트롤러로 인식@ResponseBodypublicinterfaceOrderControllerV1 {
@GetMapping("/v1/request")
Stringrequest(@RequestParam("itemId") StringitemId);
@GetMapping("/v1/no-log")
StringnoLog();
}
@RequestMapping : 스프링MVC는 타입에 @Controller 또는 @RequestMapping 애노테이션이 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL이 매핑되고 동작한다. 이 애노테이션은 인터페이스에 사용해도 된다.
@ResponseBody : HTTP 메시지 컨버터를 사용해서 응답한다. 이 애노테이션은 인터페이스에 사용해도 된다.
@RequestParam("itemId") String itemId : 인터페이스에는 @RequestParam("itemId") 의 값을 생략하면 itemId 단어를 컴파일 이후 자바 버전에 따라 인식하지 못할 수 있다. 인터페이스에서는 꼭 넣어주자. 클래스에는 생략해도 대부분 잘 지원된다.
코드를 보면 request() , noLog() 두 가지 메서드가 있다. request() 는 LogTrace 를 적용할 대상이고, noLog() 는 단순히 LogTrace 를 적용하지 않을 대상이다.
주의! - 스프링 부트 3.0 이상
스프링 부트 3.0 이상이라면 정상 동작하지 않는다. 꼭 예제 프로젝트 만들기 v1 마지막에 있는 스프링 부트 3.0 변경 사항을 확인해서 코드를 변경하자!
@Import(AppV1Config.class) : 클래스를 스프링 빈으로 등록한다. 여기서는 AppV1Config.class 를 스프링 빈으로 등록한다. 일반적으로 @Configuration 같은 설정 파일을 등록할 때 사용하지만, 스프링 빈을 등록할 때도 사용할 수 있다.
@SpringBootApplication(scanBasePackages = "hello.proxy.app") : @ComponentScan 의 기능과 같다. 컴포넌트 스캔을 시작할 위치를 지정한다. 이 값을 설정하면 해당 패키지와 그 하위 패키지를 컴포넌트 스캔한다. 이 값을 사용하지 않으면 ProxyApplication 이 있는 패키지와 그 하위 패키지를 스캔한다. 참고로 v3 에서 지금 설정한 컴포넌트 스캔 기능을 사용한다.
스프링 부트 3.0(스프링 프레임워크 6.0)부터는 클래스 레벨에 @RequestMapping 이 있어도 스프링 컨트롤러로 인식하지 않는다. 오직 @Controller 가 있어야 스프링 컨트롤러로 인식한다. 참고로 @RestController 는 해당 애노테이션 내부에 @Controller 를 포함하고 있으므로 인식 된다.
따라서 다음과 같이 변경해야 한다.
스프링 부트 3.0 미만
@RequestMapping//스프링은 @Controller 또는 @RequestMapping 이 있어야 스프링 컨트롤러로 인식@ResponseBodypublicinterfaceOrderControllerV1 {}
스프링 부트 3.0 이상
@RestController//스프링은 @Controller, @RestController가 있어야 스프링 컨트롤러로 인식publicinterfaceOrderControllerV1 {}
참고로 이후에 학습할 OrderControllerV2도 다음과 같이 @RestController 를 사용해야 한다. (바로 다음장에 설명한다.)
scanBasePackages 부분에서 마지막에 v3 가 붙었다. hello.proxy.apphello.proxy.app.v3
이렇게 하는 이유는 스프링 부트 3.0부터는 @Controller , @RestController 를 사용했는데, 이렇게 하면 내부에 @Component 를 가지고 있어서 컴포넌트 스캔의 대상이 된다. 지금 처럼 컴포넌트 스캔도 되고, 빈도 수동으로 직접 등록하게 되면 스프링 컨테이너에 등록시 충돌 오류가 발생한다. 이후에 학습할 hello.proxy.app.v3 는 빈을 직접 등록하지 않고 컴포넌트 스캔을 사용하기 때문에 괜찮다.
예제 프로젝트 만들기 v2
이번에는 인터페이스가 없는 Controller , Service , Repository 를 스프링 빈으로 수동 등록해보자.
@RequestMapping : 스프링MVC는 타입에 @Controller 또는 @RequestMapping 애노테이션이 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL이 매핑되고 동작한다. 그런데 여기서는 @Controller 를 사용하지 않고, @RequestMapping 애노테이션을 사용했다. 그 이유는 @Controller 를 사용하면 자동 컴포넌트 스캔의 대상이 되기 때문이다. 여기서는 컴포넌트 스캔을 통한 자동빈 등록이 아니라 수동 빈 등록을 하는 것이 목표다. 따라서 컴포넌트 스캔과 관계 없는 @RequestMapping 를 타입에 사용했다.
주의! - 스프링 부트 3.0 이상
스프링 부트 3.0 이상이라면 정상 동작하지 않는다. 꼭 예제 프로젝트 만들기 v1 마지막에 있는 스프링 부트 3.0변경 사항을 확인해서 코드를 변경하자!
ProxyApplication 에서 @SpringBootApplication(scanBasePackages = "hello.proxy.app") 를 사용했고, 각각 @RestController , @Service , @Repository 애노테이션을 가지고 있기 때문에 컴포넌트 스캔의 대상이 된다.
요구사항 추가
지금까지 로그 추적기를 만들어서 기존 요구사항을 모두 만족했다.
하지만 이 요구사항을 만족하기 위해서 기존 코드를 많이 수정해야 한다. 코드 수정을 최소화 하기 위해 템플릿 메서드 패턴과 콜백 패턴도 사용했지만, 결과적으로 로그를 남기고 싶은 클래스가 수백개라면 수백개의 클래스를 모두 고쳐야 한다. 로그를 남길 때 기존 원본 코드를 변경해야 한다는 사실 그 자체가 개발자에게는 가장 큰 문제로 남는다.
기존 요구사항에 다음 요구사항이 추가되었다. 요구사항 추가
원본 코드를 전혀 수정하지 않고, 로그 추적기를 적용해라.
특정 메서드는 로그를 출력하지 않는 기능
보안상 일부는 로그를 출력하면 안된다.
다음과 같은 다양한 케이스에 적용할 수 있어야 한다.
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.
Uh oh!
There was an error while loading. Please reload this page.
프로젝트 생성
프록시라는 개념을 이해하려면
프록시 패턴과 데코레이터 패턴 을 이해해야함.
이전 프로젝트를 일부 수정해서
proxy-start라는 프로젝트에 넣어두었다.프로젝트 설정 순서
proxy-start의 폴더 이름을proxy예제 프로젝트 만들기 v1
다양한 상황에서 프록시 사용법을 이해하기 위해 다음과 같은 기준으로 기본 예제 프로젝트를 만들어보자.
예제는 크게 3가지 상황으로 만든다.
v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
v2 - 인터페이스 없는 구체 클래스 - 스프링 빈으로 수동 등록
v3 - 컴포넌트 스캔으로 스프링 빈 자동 등록
실무에서는 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 있고 없는 경우도 있다. 그리고 스프링 빈을 수동으로 직접 등록하는 경우도 있고, 컴포넌트 스캔으로 자동으로 등록하는 경우도 있다. 이런 다양한 케이스에 프록시를 어떻게 적용하는지 알아보기 위해 다양한 예제를 준비해보자.
v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
지금까지 보아왔던
Controller,Service,Repository에 인터페이스를 도입하고, 스프링 빈으로 수동 등록해 보자.@RequestMapping: 스프링MVC는 타입에@Controller또는@RequestMapping애노테이션이 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL이 매핑되고 동작한다. 이 애노테이션은 인터페이스에 사용해도 된다.@ResponseBody: HTTP 메시지 컨버터를 사용해서 응답한다. 이 애노테이션은 인터페이스에 사용해도 된다.@RequestParam("itemId") String itemId: 인터페이스에는@RequestParam("itemId")의 값을 생략하면itemId단어를 컴파일 이후 자바 버전에 따라 인식하지 못할 수 있다. 인터페이스에서는 꼭 넣어주자. 클래스에는 생략해도 대부분 잘 지원된다.request(),noLog()두 가지 메서드가 있다.request()는LogTrace를 적용할 대상이고,noLog()는 단순히LogTrace를 적용하지 않을 대상이다.주의! - 스프링 부트 3.0 이상
스프링 부트 3.0 이상이라면 정상 동작하지 않는다. 꼭 예제 프로젝트 만들기 v1 마지막에 있는 스프링 부트 3.0 변경 사항을 확인해서 코드를 변경하자!
컨트롤러 구현체이다.
OrderControllerV1인터페이스에 스프링MVC 관련 애노테이션이 정의되어 있다.스프링 빈으로 수동 등록
@Import(AppV1Config.class): 클래스를 스프링 빈으로 등록한다. 여기서는AppV1Config.class를 스프링 빈으로 등록한다. 일반적으로@Configuration같은 설정 파일을 등록할 때 사용하지만, 스프링 빈을 등록할 때도 사용할 수 있다.@SpringBootApplication(scanBasePackages = "hello.proxy.app"):@ComponentScan의 기능과 같다. 컴포넌트 스캔을 시작할 위치를 지정한다. 이 값을 설정하면 해당 패키지와 그 하위 패키지를 컴포넌트 스캔한다. 이 값을 사용하지 않으면ProxyApplication이 있는 패키지와 그 하위 패키지를 스캔한다. 참고로v3에서 지금 설정한 컴포넌트 스캔 기능을 사용한다.스프링 부트 3.0(스프링 프레임워크 6.0)부터는 클래스 레벨에
@RequestMapping이 있어도 스프링 컨트롤러로 인식하지 않는다. 오직@Controller가 있어야 스프링 컨트롤러로 인식한다. 참고로@RestController는 해당 애노테이션 내부에@Controller를 포함하고 있으므로 인식 된다.따라서 다음과 같이 변경해야 한다.
스프링 부트 3.0 미만
스프링 부트 3.0 이상
참고로 이후에 학습할
OrderControllerV2도 다음과 같이@RestController를 사용해야 한다. (바로 다음장에 설명한다.)추가로
ProxyApplication도 다음과 같이 변경하자.ProxyApplication - 스프링 부트 3.0 미만
ProxyApplication - 스프링 부트 3.0 이상
scanBasePackages부분에서 마지막에v3가 붙었다.hello.proxy.apphello.proxy.app.v3이렇게 하는 이유는 스프링 부트 3.0부터는
@Controller,@RestController를 사용했는데, 이렇게 하면 내부에@Component를 가지고 있어서 컴포넌트 스캔의 대상이 된다. 지금 처럼 컴포넌트 스캔도 되고, 빈도 수동으로 직접 등록하게 되면 스프링 컨테이너에 등록시 충돌 오류가 발생한다. 이후에 학습할hello.proxy.app.v3는 빈을 직접 등록하지 않고 컴포넌트 스캔을 사용하기 때문에 괜찮다.예제 프로젝트 만들기 v2
이번에는 인터페이스가 없는
Controller,Service,Repository를 스프링 빈으로 수동 등록해보자.@RequestMapping: 스프링MVC는 타입에@Controller또는@RequestMapping애노테이션이 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL이 매핑되고 동작한다. 그런데 여기서는@Controller를 사용하지 않고,@RequestMapping애노테이션을 사용했다. 그 이유는@Controller를 사용하면 자동 컴포넌트 스캔의 대상이 되기 때문이다. 여기서는 컴포넌트 스캔을 통한 자동빈 등록이 아니라 수동 빈 등록을 하는 것이 목표다. 따라서 컴포넌트 스캔과 관계 없는@RequestMapping를 타입에 사용했다.주의! - 스프링 부트 3.0 이상
스프링 부트 3.0 이상이라면 정상 동작하지 않는다. 꼭 예제 프로젝트 만들기 v1 마지막에 있는 스프링 부트 3.0변경 사항을 확인해서 코드를 변경하자!
변경 사항
@Import(AppV1Config.class)@Import({AppV1Config.class, AppV2Config.class})@Import안에 배열로 등록하고 싶은 설정파일을 다양하게 추가할 수 있다.예제 프로젝트 만들기 v3
이번에는 컴포넌트 스캔으로 스프링 빈을 자동 등록해보자.
ProxyApplication에서@SpringBootApplication(scanBasePackages = "hello.proxy.app")를 사용했고, 각각@RestController,@Service,@Repository애노테이션을 가지고 있기 때문에 컴포넌트 스캔의 대상이 된다.요구사항 추가
지금까지 로그 추적기를 만들어서 기존 요구사항을 모두 만족했다.
하지만 이 요구사항을 만족하기 위해서 기존 코드를 많이 수정해야 한다. 코드 수정을 최소화 하기 위해 템플릿 메서드 패턴과 콜백 패턴도 사용했지만, 결과적으로 로그를 남기고 싶은 클래스가 수백개라면 수백개의 클래스를 모두 고쳐야 한다. 로그를 남길 때 기존 원본 코드를 변경해야 한다는 사실 그 자체가 개발자에게는 가장 큰 문제로 남는다.
기존 요구사항에 다음 요구사항이 추가되었다.
요구사항 추가
가장 어려운 문제는 원본 코드를 전혀 수정하지 않고, 로그 추적기를 도입하는 것이다. 이 문제를 해결하려면 프록시(Proxy)의 개념을 먼저 이해해야 한다.
All reactions