스프링 에서는 기존 서블릿 파일 이름이였던, FrontController를
DispatcherServlet 로 사용 한다.
1.
기존, controller.jsp의 코드를 FrontController.java 서블릿으로 옮겨 왔다.
>> 유지 보수 불리
2.
그래서, XxxAction 클래스로 모듈화를 진행 했다.
XxxAction 클래스 내부에는, execute(request, response) 메서드가 있었다.
이러한 Action 류 클래스는 공통적으로 execute() 메서드를 사용하기도 하고,
하드 코딩 하는것을 줄이기 위해서, Action 인터페이스를 생성 했고,
Action류 클래스들은 이 Action 인터페이스를 구현 했다.
3.
Spring 에서는 이 XxxAction 클래스를,
XxxController 으로 사용 한다.
(클래스명이 XxxController)
또한, 내부에 있는 execute() 메서드 명을
handleRequest(request, response) 로 사용 한다.
마찬가지로 XxxController 클래스들은 Controller 인터페이스를 구현 한다.
4.
기존에 execute() 메서드의 반환값은 ActionForward 자료형 이였는데,
이 handleRequest(request, response) 메서드의 반환타입은 String 타입 이다.
반환값으로 String 타입을 사용 하고,
위의 코드는 경로 (path) 를 보내주는 기능을 하는 코드 이다.
반환값으로, ActionForward 객체 대신에, String 타입을 사용해서 훨씬 가볍다.
기존 FrontController.java (서블릿) 에서 XxxAction 류 클래스들은,
forward 객체에 필요한 데이터를 set 해서 forward 객체를 반환 했다.
5.
1) 이런식으로 작성된 코드는, 싱글톤 패턴이 깨지는 개념이고,
2) new (객체화) 를 직접 작성 하는 문제점이 있기에,
(결합도가 증가하고, 유지보수불리)
>> 싱글톤 패턴이 깨지지 않도록 팩토리 패턴을 활용 한다.
기존 FrontController 에서는 사용자가 페이지를 요청 할 때마다,
매번 새롭게 요청에 필요한 자료형을 new 해서 객체화 해줬다.
즉, 요청이 들어올때마다 객체화를 매번 하기 때문에 싱글톤 패턴이 깨지는 개념.
이런식으로, command (요청) 이 들어오면, 들어올때마다 매번 new 해주는 모습을 확인.
6. 싱글톤 패턴이 깨지지 않도록 팩토리 패턴을 활용 하기.
HandlerMapping 이라고 한다.
DispatcherServlet 에서 사용 되는 factory 클래스의 이름을 HandlerMapping 이라 한다.
팩토리 패턴을 사용 하기에, 싱글톤 개념이 유지 된다.
Factory 패턴 이란 ?
객체를 생성하는 코드를 캡슐화 하여,
== new 키워드와 관련된 코드를 은닉 (Hiding)
사용자로부터 필요한 객체의 이름을 받아, 객체 자체를 반환하는 로직을 의미.
Singleton 패턴 이란 ?
디폴트로 객체를 1개만 메모리에 생성하고, 해당 객체를 재사용 한다.
(메모리 전체에 같은 타입의 객체를 1개만 생성 == 재사용)
멤버 (변수) 로 Map<String,Controller> mappings; 를 사용 하는 모습을 확인.
Controller는 XxxController 클래스들이 구현하기 위한 인터페이스 이다.
(XxxController은 기존의 XxxAction)
즉, 사용자가 요청을 하면 ~ (command)
해당 요청값 (== command == key) 에 대한 key value 로 (값),
Controller 인터페이스 타입을 get 해서 반환하기 위함 이다.
[ 참고 ]
getter을 생성하지 않고, getController(String command) 라는 메서드를 작성한 이유
당연히 getter을 생성하면 return 값으로 mapping을 반환 한다.
근데, 반환 해야하는 대상이, Map 클래스의 참조변수인 mappings 가 아니라,
Map<String,Controller> 에서 특정 키에 (요청 == command) 대한 값인,
Controller 자료형을 반환 해야 하니까,
getController(String command) 라는 메서드를 작성 했다.
위와 같이 코드를 작성 했을 때, 싱글톤이 유지 되는 이유는 다음과 같다.
사용자가 요청한 값 == command가,
getController(String command) 메서드의 인자로 들어왔을 때,
mappings 를 주체로 해서, get(command)를 하는데,
즉, get(key == command) 해서, 키에 대한 값을 return 하게 된다.
이 키에 대한 값은 아래와 같다.
키가 main.do 였으면, 키에 대한 값으로 new MainController() 를 return 한다.
키가 login.do 였으면, 키에 대한 값으로 new LoginController() 를 return 한다.
이때, new 자료형() 은, 이미 HashMap 에 저장되어 있는 객체 라서
여러번 객체화가 되는 개념이 아니라,
HashMap 에 처음 저장될 때, 딱 한번만 객체화 되서 저장되는 개념 이다.
그래서, 싱글톤이 유지 된다.
여기서 짚고 넘어가야 하는 개념
mappings 가 주체가 되어, 메서드를 호출 하는 상황 이기에,
즉, 객체를 사용 해야 하기 때문에, 객체화가 필요 하다.
따라서, HandlerMapping 자료형 (클래스) 과 Map mappings 는
서로 의존관계 이며, 의존성 주입이 필요 하다.
이때,
mappings는 다양한 의존 주입 방법 중에서,
생성자로 의존 주입을 한다.
정리하자면,
요청값 (command == key) 에 대해, XxxController 객체를 반환 한다.
7.
반환된 XxxController 객체를 DispatcherServlet 에서 받는다.
받기 위해서,
당연히,
HandlerMapping 자료형의 참조변수가 선언 되어 있어야 하며,
DispatcherServlet 서블릿 에서 HandlerMapping 자료형의 객체를 사용 하기에,
둘은 의존 관계 이며,
HandlerMapping 자료형을 객체화 해야 한다.
이때, HandlerMapping 자료형을 객체화 하기 위한 방법으로는,
예외적으로, init() 메서드를 사용 해서 의존성 주입을 진행 한다.
즉,
DS (DispatcherServlet) 에서는 HM (handlerMapping) 을 멤버로 활용 하고,
HM에 대한 DI는 init() 메서드로 처리.
팩토리 패턴을 사용 했기에, 기존 FrontController.java 서블릿 코드와 다르게,
코드가 간결해진 모습을 확인 할 수 있다. (new 하는 모습이 없음)
'Spring 프레임워크 > 이론' 카테고리의 다른 글
Spring MVC 패턴의 구조 파악 2 (Controller 파트) (0) | 2023.08.03 |
---|---|
Spring MVC 패턴의 구조 파악 (Model 파트) (0) | 2023.08.02 |
IoC 로 객체를 호출 하기 (어노테이션 & .xml) (0) | 2023.08.01 |
Spring 프레임워크 기본 개념 (개요) 2 (0) | 2023.08.01 |
Spring 프레임워크 기본 개념 (개요) (0) | 2023.07.31 |