일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- electron
- AI/GPT
- 알고리즘
- 개발/네트워크
- 개발
- 개발/프레임워크&라이브러리
- 개발/Electron
- 대외활동/카카오테크캠퍼스
- 카카오 테크 캠퍼스
- 카테캠
- 개발/Tools/프레임워크/Spring
- ⌨️Developer/보안
- ⌨️Developer
- 개발/OOP
- 카카오테크캠퍼스
- 개발/CS/OS
- 개발/MySQL
- 개발/CS/알고리즘
- AI/ML
- 개발/언어/Java
- 개발/컴퓨터네트워크
- 취업
- 개발/보안
- ai
- 개발/환경
- 개발/Java
- 개발/에러
- 개발/webrtc
- 개발/언어론
- 개발/Java/Spring
- Today
- Total
봄수의 연구실
DispatcherServlet은 어떻게 View와 Controller를 구별할까 본문
- <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 |