-
Spring Core - 프록시 패턴(예제 프로젝트)FrameWork/Spring&Spring-boot 2024. 3. 8. 11:02
프록시패턴 - 예제 프로젝트
다양한 상황에서 프록시 사용법을 이해하기 위해 다음과 같은 기준으로 기본 예제 프로젝트를 만들어보자
예제는 크게 3가지 상황으로 만든다.
- v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
- v2 - 인터페이스 없는 구체 클래스 - 스프링 빈으로 수동 등록
- v3 - 컴포넌트 스캔으로 스프링 빈 자동 등록
실무에서는 스프링 빈으로 등록할 클래스는 인터페이스가 있는 경우도 있고 없는 경우도 있다. 그리고 스프링 빈을 수동으로 직접 등록 하는 경우도 있고, 컴포넌트 스캔으로 자동으로 등록하는 경우도 있다. 이러한 다양한 케이스에 프록시를 어떻게 적용하는지 알아보기 위해 다양한 예제를 준비해보자.
예제 프로젝트 만들기 v1
v1 - 인터페이스와 구현 클래스 - 스프링 빈으로 수동 등록
지금까지 보았던 Controller, Service, Repository에 인터페이스를 도입하고, 스프링 빈으로 수동 등록해보자.
OrderRepositoryV1
public interface OrderRepositoryV1 { void save(String itemId); }
OrderServiceV1
public interface OrderServiceV1 { void orderItem(String itemId); }
OrderControllerV1
@RequestMapping @ResponseBody public interface OrdersControllerV1 { @GetMapping("/v1/order") String createOrder(@RequestParam("itemId") String itemId); @GetMapping("/v1/no-log") String noLog(); }
- @RequestMapping : 스프링 MVC는 @RestController 또는 @RequestMapping 에노테이션이 타입이 있어야 스프링 컨트롤러로 인식한다. 그리고 스프링 컨트롤러로 인식해야, HTTP URL이 매핑되고 동작한다. 이 애노테이션은 인터페이스에 사용해도 된다.
- @ResponseBody : HTTP 메시지 컨버터를 사용해서 응답한다. 이 애노테이션은 인터페이스에 사용해도 된다.
- 코드를 보면 createOrder(), noLog() 두 가지 메서드가 있다. createOrder()는 LogTrace를 적용할 대상이고, noLog()는 단순히 LogTrace를 적용하지 않을 대상이다.
@RequestParam("itemId") 같은 어노테이션은 클래스 레벨에서는 생략해도 크게 문제가 없지만 인터페이스의 경우는 제대로 명시해 주는 것이 좋다 그렇게 하지 않을 경우 컴파일 시점에 인식이 안돼는 문제가 발생할 수 있다.
SpringProxyApplication - 코드 추가
@Import(AppV1Config.class) @SpringBootApplication public class SpringProxyApplication { public static void main(String[] args) { SpringApplication.run(SpringProxyApplication.class, args); } }
- @Import(AppV1Config.class) : 클래스를 스프링 빈으로 등록한다. 여기서는 AppV1Config.class를 스프링 빈으로 등록한다. 일반적으로 @Configuration 같은 설정 파일을 등록할 때 사용하지만, 아무 빈이나 수동 등록할 때도 사용할 수 있다. 스프링 빈을 등록할 때 사용할 수 있다.
- AppV1Config 클래스 자체가 스프링 빈으로 등록되 되야 해당 클래스 하위에 @Bean 어노테이션으로 등록한 빈들도 스프링 빈으로 등록이 된다.
- @SpringBootApplication(scanBasePackages = "hello.proxy.app") : @ComponentSacn의 기능과 같다 컴포넌트 스캔을 시작할 위치를 지정한다. 이 값을 설정하면 해당 패키지와 그 하위 패키지를 컴포넌트 스캔한다. 이 값을 사용하지 않으면 SpringProxyApplication이 있는 패키지와 그 하위 패키지를 스캔한다. 참고로 v3에서 지금 설정한 컴포넌트 스캔 기능을 사용한다.
❗주의
앞으로는 @Configuration을 사용한 수동 빈 등록 설정을 com.core.springproxy.config 위치에 두고 점진적으로 변경할 예정이다. 지금은 AppV1config.class를 @Import를 사용해서 설정하지만 이후에 다른 것을 설정할 예정이다.
@Configuration은 내부에 @Component 애노테이션을 포함하고 있어서 컴포넌트 스캔의 대상이 된다. 따라서 컴포넌트 스캔에 의해 hello.proxy.config 위치 설정 파일들이 스프링 빈으로 자동 등록 되지 않도록 컴포넌트 스캔의 시작 위치를 "com.core.springproxy.app" 으로 설정해야 한다.
예제 프로젝트 만들기 v2
v2 - 인터페이스 없는 구체 클래스 - 스프링 빈으로 수동 등록
이번에는 인터페이스가 없는 Controller, Service, Repository를 스프링 빈으로 수동 등록해보자
OrderContorllerV2
package com.core.springproxy.app.v2; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @Slf4j @RestController @ResponseBody public class OrderControllerV2 { private final OrderServiceV2 orderService; public OrderControllerV2(OrderServiceV2 orderService) { this.orderService = orderService; } @GetMapping("/v2/order") String createOrder(@RequestParam("itemId") String itemId){ orderService.orderItem(itemId); return "ok"; } @GetMapping("/v1/no-log") String noLog(){ return "ok"; } }
예제 프로젝트 만들기 v3
v3 - 컴포넌트 스캔으로 스프링 빈 자동 등록
이번에는 컴포넌트 스캔으로 스프링 빈을 자동 등록해보자.
@Slf4j @RestController @ResponseBody public class OrderControllerV3 { private final OrderServiceV3 orderService; public OrderControllerV3(OrderServiceV3 orderService) { this.orderService = orderService; } @GetMapping("/v3/order") String createOrder(@RequestParam("itemId") String itemId){ orderService.orderItem(itemId); return "ok"; } @GetMapping("/v3/no-log") String noLog(){ return "ok"; } }
ProxyApplication 에서 @SpringBootApplication(scanBasePackage = "com.core.springproxy")를 사용했고, 각각 @RestController, @Service, @Repository 애노테이션을 가지고 있기 때문에 컴포넌트 스캔 대상이 된다.
[출처 - 스프링 핵심원리-고급편, 저 김영한]
'FrameWork > Spring&Spring-boot' 카테고리의 다른 글
Spring Core - 프록시 패턴(예제1,예제2,Cache Proxy) (0) 2024.03.08 Spring Core - 프록시 패턴, 데코레이터 패턴 - 소개(요구사항 추가) (0) 2024.03.08 Spring Core - 템플릿 콜백 패턴(시작, 적용, 정리) (0) 2024.03.07 Spring Core - 전략 패턴(시작, 예제1, 예제2) (1) 2024.03.07 Spring Core - 템플릿 메서드 패턴(예제3, 적용1, 적용2) (0) 2024.03.06