TIL

2021.08.20 기록장

Gisungcu 2021. 8. 19. 23:40

ToDo

  • 알고리즘 문제
  • 토비의 스프링

Done

  • 토비의 스프링

Weekly goal

  • 책 읽기
  • 토비 스프링 코딩
  • 7월 회고 쓰기

 

토비의 스프링

 

633p.

스프링 3.1 이후부터는 어노테이션 관련 매핑 전략이 변경이 되었다.

이유는 원래 스프링 mvc에서 플로우사 매핑이 되돌려주는 것은 컨트롤러 오브젝트이다. 어댑터는 그 컨트롤러 어댑터를 받아서 메서드를 실행시키는 것이다.

근데 @RequestMapping은 메서드 메서드 단위로 붙일 수 있다. 그래서 3.0 버전에서는 DefaultAnnotationHandlerMapping을 사용하는데 이는 해당 메서드가 존재하는 컨트롤러 오브젝트를 돌려주고 AnnotationMethodHandlerAdapter에서 직접 메서드를 찾는 로직이 들어갔다. 그래서 로직에서 리플렉션 등이 등장했고 확장 불가능한 안 좋은 모습이었다.

 

3.1에서는 이 부분을 탈피하기 위해서 핸들러 매핑 시 컨트롤러가 아닌 HandlerMethod를 반환하는 RequestMappingHandlerMapping을 사용한다. 어댑터도 메서드를 바로 실행하는 RequestMappingHandlerAdapter를 사용한다.

토비의 스프링Vol.2

또 3.1 이전에는 인터셉터를 걸기도 애매했다. 오브젝트 단위로 넘겨주는데 실제 실행은 오브젝트 내의 하나의 메서드이니 불가했던 것이다.

하지만 이제는 HandlerInterceptorAdapter를 확장하면 넘어오는 Object는 컨트롤러가 아닌 HandlerMethod가 넘어온다.

 

638p.

HandlerMethod는 @RequestMapping이 붙은 메서드의 정보를 추상화한 오브젝트 타입이다.

이는 그 자체로 실행할 수 있는 오브젝트는 아니다. 다만 메서드를 실행하는데 필요한 참조 정보가 들어있다.

어댑터는 이를 활용해서 간접적으로 실행하는 것이다.

HandlerMethod가 가지고 있는 핵심 정보는

빈 오브젝트

메서드 메타정보

메서드 파라미터 메타정보

메서드 애너테이션 메타정보

메서드 리턴 값 메타정보

등이다.

 

근데 이런 HandlerMethod정보는 놀랍게도 필요할 때 만들어지는 것이 아니다.

언제 만들어지냐면 DispatcherServlet이 시작될 때 모든 컨트롤러 빈을 살펴서 메서드를 HandlerMethod형태로 저장을 한다.

 

디스패처 서블릿이 사용할 전략들은 spring-webmvc.jar에 있는 DispatcherServlet.properties안에 들어있다.

 

642p.

이제 RequestMappingHandlerMapping가 어떻게 매핑을 해서 메서드를 찾을까를 알아보자,

기본적인 메서드 찾는 전략들은 RequestCondition 인터페이스를 구현한 클래스로 만들어져 있다.

구현한 클래스는 다른 구현 클래스들과 결합하여 새로운 RequestCondition클래스를 만들 수 있다.

위들의 정보를 @RequestMapping에 넣을 수 있다 이를 요청정보라고 한다. 브라우저에서 http 요청이 들어오면 @RequestMapping에 있는 요청정보와 맞는 애를 찾는다. 메소들 레벨이 붙어있는 요청정보도 보고 클래스 레벨에 붙어있는 요청정보도 보기 때문에 실질적으로 14가지의 요청정보가 있는 것이다.

 

RequestCondition로 구현한 메서드 요청정보 매핑 클래스들은 위의 정보를 이용해서 찾아준다.

url 같은 경우에는 클래스 레벨이 있는 것과 경우의 수를 맞춰서 || 연산자를 통해 찾고 파라미터 같은 경우는 && 연산자를 통해 찾는다.

 

650p.

몇 가지 파라미터 어노테이션을 알아보자. 이들이 붙어있음 어댑터에서 마지막 검증을 진행할 것이다.

@Validated/@Valid인데 앞에 꺼는 그룹을 지정할 수 있다. 예로 Admin은 id가 null이어도 된다든지 User는 권한이 null이어도 된다든지를 정할 수 있다.

 

667p.

이전에도 말했듯이 spring은 시작 시 2개의 콘텍스트를 생성한다. 하나는 루트 콘텍스트이고 하나는 서블릿 콘텍스트이다.

루트 콘텍스트에는 인프라 빈(DataSource, TransactionManager 등..)과 서비스나 리포지토리 빈들이 생성되고 서블릿 콘텍스트에는 web관련 빈들이 생성된다. 

근데 여태 말했던 것들 Mapping 등은 루트 콘텍스트 말고 서블릿 콘텍스트가 어울린다.

그래서 인터페이스로 WebMvcConfigurer가 존재한다. 이를 통해 설정할 수 있다.

 

자료구조

map과 list

리스트는 중복이 허용되고 순서가 있다.

map은 순서가 없고 키 밸류 값으로 저장된다.

 

linkedList와 ArrayList

 

ArrayList는 내부에 있는 배열에 값들을 저장함, 인덱스가 존재하여 바로 접근 가능

데이터 추가, 삭제 시 배열 추가 위치 전까지 배열을 복사해서 만들고 추가하고 뒤에를 다시 복사해서 넣음 이는 성능에 영향을 미칠 수 있음.

linkedList는 양방향 포인터 구조임 데이터의 삽입 삭제가 빈번할 때 성능을 보장함.

중간에 끊고 양방향으로 포인터를 다시 붙이면 되니까.

접근 시 앞에서 부터 타고 들어가야 함.