java-was mission(Reflections 라이브러리 사용)
팀 프로젝트를 하기 전 마지막 미션, 마지막 pr을 보냈다.
리뷰는 브라이언이 해주셨다.
이렇게 돼서 제목은 was인데 spring mvc를 흉내 내게 되었다.
아무래도 RequestHandler의 리팩터링에만 집중하다 보니 다른 부분에서의 else문이 많이 등장하게 되었다.
중간에 return을 시켜줘서 보이기는 else를 줄였는데, 음 브라이언이 원했던 건 이게 아니었을 거 같다 ㅋㅋ
다음은 HttpRequest를 생성하는 of 메서드이다.
내부에서 HttpRequest를 제조하는 많은 메서드들이 들어가 있는데 static메서드에 많은 구현이 들어가 있는 것은 좋지 않다고 하신다.
이 부분은 아직 구현하지 않았다. 방법이 생각나지 않는다.
이번 새롭게 도입한 부분이다.
이전 코드는 새로운 요청이 있으면 새로운 controller를 만들어서 map에 등록해주는 과정이 필요했다.
브라이언은 이 부분 수정을 요구하셨다.
처음 요구사항을 봤을 때는 감이 안 잡혔다.
처음에 모든 controller를 다 map에 넣는 부분을 어노테이션과 리플렉션을 통해 자동화하기로 했다.
동작 순서는 다음과 같다.
0. RequestMapping 어노테이션을 정의한다. 이 어노테이션은 controller에 붙여 사용한다.
1. 브라이언 말대로 중간에 class를 둔다. 이름은 adapter로
2. 그 adapter는 @RequestMapping이 붙어 있는 controller를 Map에 집어넣는다.
3. RequestHandler는 main에서 생성한 map(adapter)을 받아서 사용한다.
4. RequestHandler의 run method는 Request를 만들고 나서 method와 url을 통해 map에서 controller를 꺼내서 사용한다.
이제 코드로 알아보자.
0.
controller들에게 붙일 어노테이션을 정의했다. class에 붙일 거고, 정보는 런타임 시점까지 가져갈 거다.
지금은 class 하나당 특정한 request 요청 하나와 매칭 되어 있다.
spring은 메서드 하나와 매칭 되긴 하는데..
어노테이션에 controllerKey를 만들 때 필요한 method와 url을 받아서 관리한다.
나중에 저 필드들을 리플렉션으로 꺼내서 map에 등록을 할 거다.
1.
필드로는 디폴트 컨트롤러와 map을 가진다. static은 긁어오면서 같이 가져왔는데 필요 없다.
2.
이제 Reflections 라이브리를 사용할 차례이다.
java의 reflection은 특정 class를 알려줘야 하는데 이 라이브러리는 패키지 밑에 있는 class들을 reflection을 할 수 있다.
www.javadoc.io/doc/org.reflections/reflections/0.9.10/org/reflections/Reflections.html
Reflections - reflections 0.9.10 javadoc
Latest version of org.reflections:reflections https://javadoc.io/doc/org.reflections/reflections Current version 0.9.10 https://javadoc.io/doc/org.reflections/reflections/0.9.10 package-list path (used for javadoc generation -link option) https://javadoc.i
www.javadoc.io
controller 패키지 밑에 있는 class 들을 뒤져서 RequestMapping 어노테이션이 붙어 있는 class 들을 set으로 가지게 한다.
set으로 뽑아낸 것들을 이제 하나하나 map에 등록을 해준다.
어노테이션에서 url과 method를 뽑아내서 controllerkey를 만들고 런타임 시점에 객체로 만들어 등록해준다.
이제 이 adapter를 사용해서 controller를 받을 수 있게 했다.
정의된 게 없는 요청일 경우 defaultController를 반환한다.
3.
main에서는 이제 adapter만 생성해서 RequestHandler에 넘겨주면 된다.
4.
생성자를 통해 받은 adapter를 필드에 저장하고 사용한다.
외부에서 Request 요청이 들어오면 그 요청에서 method와 url을 꺼내서 ControllerKey를 만든다.
equals와 hashcode를 재정의해놔서 동일성을 보장해준다.
외부 요청을 통해 만든 controllerKey를 통해 controller를 꺼내서 service를 실행시킨다.
그럼 다형성을 이용해서 재정의된 service가 실행될 거다.
그럼 끝이다.
reflection을 어떻게 이용해야 할까 고민이 많았는데
외부 라이브러리인 reflections를 K가 생각해 내어서 마무리가 쉽게 되었다.