- <a href="https://berom.tistory.com/251">DispatcherServlet</a>은 class의 annotation 유무를 보고 구분을 한다
실제 코드는 Github 링크를 참고하면 된다!
아래는 예제 프로젝트의 파일들이다.
딱 보니, 여러 개의 controller와 Spring의 @RequestMapping이 보인다
프로세스
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String uri = sc.nextLine();
Set<Class> classes = componentScan("ex03");
findUri(classes, uri);
}
처음 프로젝트를 실행시키면, URI 입력 받고, 입력 받은 데이터를 잘라서 findURI에 넣는다
또한, ex03 프로젝트를 scan해서 클래스들 또한 입력한다
이제 우리가 주목해야 할 것은 App.java의 finduri이다.
public static void findUri(Set<Class> classes, String uri) throws Exception {
boolean isFind = false;
for (Class cls : classes) {
if (cls.isAnnotationPresent(Controller.class)) {
Object instance = cls.newInstance();
Method[] methods = cls.getDeclaredMethods();
for (Method mt : methods) {
Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class);
RequestMapping rm = (RequestMapping) anno;
if (rm.uri().equals(uri)) {
if(mt.isAnnotationPresent(ResponseBody.class)){
mt.invoke(instance);
return MessageConverter.convert(result)
}
else{
String fileName = (String) mt.invoke(instance);
return ViewResolver.convert(fileName);
}
}
}
}
}
if(isFind == false){
System.out.println("404 Not Found");
}
}
프로젝트 내부의 클래스를 순회하면서 일단 controller 어노테이션이 있는지 찾는다
즉 Controller를 조회하는 것이다
만약 Controller가 있다면, 클래스의 인스턴스를 생성하고, 메소드를 배열에 저장한다
if (cls.isAnnotationPresent(Controller.class)) {
Object instance = cls.newInstance();
Method[] methods = cls.getDeclaredMethods();
다음은 역시 해당 메소드에 RequestMapping 어노테이션을 갖고 온다.
이제 매개변수로 전달 받은 URI와 RequestMapping의 URI가 동일한지 확인한다
for (Method mt : methods) {
Annotation anno = mt.getDeclaredAnnotation(RequestMapping.class);
RequestMapping rm = (RequestMapping) anno;
if (rm.uri().equals(uri)) {
// 아래 코드가 있습니다
}
}
if (rm.uri().equals(uri))
내에서는 Response Body 어노테이션이 붙어있으면 메시지 컨버터를 발동시킨다
그렇지 않다면 뷰 리졸버를 발동시킨다!
if(mt.isAnnotationPresent(ResponseBody.class)){
// 메시지 컨버터 발동
mt.invoke(instance);
return MessageConverter.convert(result)
}
else{
// 뷰 리졸버 발동
String fileName = (String) mt.invoke(instance);
return ViewResolver.convert(fileName);
}
Converter가 뭔데?
예시로 ViewResolver의 Converter를 보자
위의 코드를 보면, Object를 json으로 변경 시켜준다.
변경 된 데이터를 buffer에 담아서 html로 읽어 반환해버린다
결론
Spring에서 요청이 들어오면, 아래의 흐름으로 처리가 된다
- 톰켓(sockt으로 구성,request 객체 생성 후 반환) -> 필터 -> DispatcherServlet - controller - service - repository
[[DispatcherServlet]]이 이렇게 중요하다…!
중간에서 적절하게 경로를 라우팅 해줌으로써 유지보수가 수월해지게 해준다
이래서, 사람들이 Spring을 사랑하나보다
부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>
'DEV > Java' 카테고리의 다른 글
Meta 어노테이션 (0) | 2023.07.07 |
---|---|
IoC (0) | 2023.07.07 |
DispatcherServlet 왜 필요한가 (0) | 2023.07.05 |
Spring의 @RequestMapping (0) | 2023.07.05 |
Spring Security (0) | 2023.07.04 |