2021.09.22 - [Java/Spring 기초] - [Spring 기초] Spring 3대 요소 (2) Aspect Oriented Programming
이전 글에 이어 이번에는 Spring 3대 요소 중 세 번째인 PSA (Portable Service Abstraction) 에 대해서 알아보고자 한다.
(이번 글도 백기선님의 강의 를 참고해서 정리했다.)
PSA 란 무엇인가 ?
PSA 란 백기선 님의 말을 빌리자면 '잘 만든 인터페이스' 라고 한다. (처음에는 좀 잘 안 와닿았는데 몇 가지 예시를 보니 이해가 갔다.)
내 이해로는 추상화가 굉장히 잘 된 인터페이스라고 이해했다.
작업 환경이나 기술이 변화더라도 일관된 방식의 접근 방식을 제공하여 의존성을 크게 고려하지 않아도 되는 구조라고 이해했다.
저번 글에서 어노테이션이 있으면 해당 어노테이션이 붙은 클래스에 부가 기능을 붙일 수 있는 AOP 에 대해서 알아보았다.
그의 예시로 트랜젝션 어노테이션을 들었는데 이 트랜젝션 어노테이션이 붙은 Class 는 자동적으로 try catch 가 붙게 된다.
그러나 만약 JPA 를 이용해 JpaTransacionManager 를 사용하고 있었는데 JDBC 로 기술을 바꾸어 DatesourceTransactionManager 를 사용해야 한다고 가정하자.
이때 코드는 거의 변경할 필요가 없다. (추상화가 잘된 인터페이스이기 때문이다.)
이러한 트랜젝션 어노테이션도 PSA 가 적용된 예시이다.
또 다른 예시로는 Controller 어노테이션과 RequestMapping 어노테이션이 있다.
오늘도 역시 예시 코드 를 이용했다.
Controller 어노테이션이 붙으면 요청을 매핑할 수 있는 컨트롤러 역할의 클래스가 되는데 이 클래스 내부에서 GetMapping 또는 PostMapping 의 어노테이션이 붙으면 뒤의 붙은 url 로 요청이 들어왔을 때 해당 어노테이션이 붙은 클래스에서 요청을 처리해준다.
여기서 쓰인 GetMapping 함수를 조금 뜯어보면
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(
method = {RequestMethod.GET}
)
public @interface GetMapping {
@AliasFor(
annotation = RequestMapping.class
)
String name() default "";
@AliasFor(
annotation = RequestMapping.class
)
String[] value() default {};
@AliasFor(
annotation = RequestMapping.class
)
String[] path() default {};
@AliasFor(
annotation = RequestMapping.class
)
String[] params() default {};
@AliasFor(
annotation = RequestMapping.class
)
String[] headers() default {};
@AliasFor(
annotation = RequestMapping.class
)
String[] consumes() default {};
@AliasFor(
annotation = RequestMapping.class
)
String[] produces() default {};
}
name, value, path, params 등등 이렇게 많은 속성을 가지고 있다는 것을 볼 수 있다.
이 속성들은 전부 요청과 관련이 있는데 요청이 들어오는 경로, 헤더, 파라미터 등이 있을 때
매핑되는 요청이 있다면 해당 어노테이션이 붙은 컨트롤러 함수가 실행되는 것이다.
해당 컨트롤러 함수 내부에서 Model 을 객체에 담아 View 에 전달해 리턴해주는 것을 볼 수 있다.
이것이 spring 에서 제공해주는 MVC 추상화 계층인데 이것 역시 PSA 의 예시이다.
원래 톰캣 환경의 Java 에서 Client 의 요청을 받아오기 위해서 HttpServelet 을 이용해야 하는데
Spring 의 @Controller 와 @RequestMapping 에노테이션을 사용하면 HttpServelet Class 가 없어도 Http 통신을 할 수 있다.(Spring 이 다 알아서 해주기 때문이다.)
low level 까지 신경 쓰지 않아도 클라이언트와 요청을 주고받을 수 있는 추상화가 잘 된 예시이다.
(사용자에게 편의성을 제공해준다.)
기본적으로 spring boot 기반의 애플리케이션을 실행하면 톰캣 기반으로 실행이 되는 것을 확인할 수 있는데 그럼 톰캣이 아닌 네티나 제티, 언더토우 기반으로 실행하고 싶다면 어떻게 하면 좋을까 ??
PSA 가 적용되었기 때문에 코드는 거의 변경하지 않은 상태로 손쉽게 다른 기술 스택으로 갈아 끼울 수 있다.
pom.xml 파일에 들어가서 dependency 를 수정해주는데
기존의 web 으로 되어 있던 부분을 webflux 로 수정해준다.
<!-- 기존 코드 주석 -->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
대신 위처럼 바꾸면 더 이상 ModelAndView 를 사용할 수 없게 되므로
OwnerController 의 ModelAndView 를 사용한 코드도 주석처리해준다. (맨 마지막 함수)
그리고 다시 애플리케이션을 실행해보면 Netty 기반으로 실행된 것을 볼 수 있다.
톰캣 환경의 코드를 거의 변경하지 않고 네티 기반으로 바꾼 것이다 !
이것이 바로 PSA 의 예시이다.
이렇게 Spring 의 3대 주요 개념 (IoC/DI, AOP, PSA) 중 마지막으로 PSA 에 대해서 알아보았다.
이 3대 개념은 스프링의 철학에 대한 것이며 이를 통해 스프링이 지향하는 것과 그 가치에 대해서 알 수 있었다. (잊지 말자 !!)
스프링을 이제 막 입문했지만 벌써 친구가 된 기분이다. (물론 기분 탓이겠지만 ...)
'Java > Spring 기초' 카테고리의 다른 글
[Spring 기초] Spring 3대 요소 (2) Aspect Oriented Programming (0) | 2021.09.22 |
---|---|
[Spring 기초] Spring 3대 요소 (1) Inversion of Control (0) | 2021.09.19 |
댓글