1. Spring MVC 구조
MVC 패턴은 애플리케이션의 각 영역을 Model, View, Controller 로 역할을 나누어 설계하는 디자인 패턴이다. 각 영역의 역할은 다음과 같다.
- Controller: HTTP 요청을 받아 파라미터를 검증하고 비즈니스 로직을 실행한다. View 에 전달할 결과 데이터를 모델에 담아서 반환한다. 이때 Controller 와 Model 사이에 Service layer 를 두어서 실제 비즈니스 로직을 구현한다.
- Model: view 에 출력할 데이터를 저장하고 있다. Controller 에서 요청이 들어왔을 때 조회, 삽입, 삭제, 수정 등의 데이터를 다루는 동작을 수행한다.
- View: 모델에 담겨있는 데이터를 사용하여 화면에 렌더링한다.
- Spring MVC 동작 구조
스프링 프레임워크에 대한 HTTP 요청은 모두 DispatcherServlet 을 거쳐서 들어온다. DispatcherServlet 은 요청 url 에 매핑되는 컨트롤러를 찾고, 해당 컨트롤러를 통해 요청을 처리한 결과를 View 로 반환해 렌더링 해주는 역할을 한다.
1. HTTP 요청이 들어오는 경우 먼저 HandlerMapping 을 통해 해당 요청에 매핑되는 Handler (컨트롤러) 를 조회한다.
2. 조회된 Handler 를 사용하기 위하여 HandlerAdapter 와 연결한다.
3. 컨트롤러와 연결된 HandlerAdapter 를 실행하여 요청을 처리한다.
4. HandlerAdapter 를 통해서 실행된 컨트롤러는 Model 의 로직을 통해서 요청을 처리하고 Model 객체에 결과를 적용한 후에 적절한 View 이름을 결과로 반환한다.
5. HandlerAdapter 는 컨트롤러를 통해 전달받은 View 와 Model 객체를 ModelAndView 객체로 DispatcherServlet 에게 반환한다.
6. DispatcherServlet 은 전달받은 결과 View 를 렌더링 하는데, 이때 ViewResolver 를 통해서 매핑되는 View 를 조회한다.
7. ViewResolver 가 조회한 View 를 반환하고 이를 렌더링한다.
2. Controller
Model 과 View 를 연결해주는 역할을 한다. 각 컴포넌트와 연결되어 있고, 이에 대한 요청을 인지하여 대처해야한다.
Controller 는 HTTP 요청을 받아서 파라미터를 검증하거나 비즈니스 로직을 수행하는 역할을 맡는다.
구현 시에 @Controller 어노테이션을 사용하여 Controller 역할을 할 클래스를 지정할 수 있다. 이때 @RequestMapping 어노테이션을 사용하여 해당 클래스나 메서드에 매핑될 HTTP 요청 url 을 지정할 수 있다.
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/")
public Map<Object, Object> getUser(@RequestParam String id) {
Map<Object, Object> map = new HashMap<>();
User user = userService.getUser(id);
map.put("user", user);
return map;
}
}
2 – 1. Service
실제 Controller 를 구현할 때 복잡한 비즈니스 로직을 모두 Controller 에 넣지는 않는다. 코드의 복잡성과 책임을 분리하기 위해서 보통 Service layer 를 두어서 비즈니스 로직을 구현한다.
Service 는 Controller 에서 호출하는 비즈니스 로직이 구현된 layer 로 Model 에 필요한 데이터 작업을 처리한다. 해당 어노테이션으로 지정되면 별다른 기능은 없이 @Component 어노테이션과 같이 Spring Context 에 Bean 으로 등록된다.
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Override
public User getUser(String id) {
User user = userRepository.findById(id);
return user;
}
}
2-2. Repository
애플리케이션에서 데이터를 저장하고 관리하는 저장소를 가지고 있는데, 이를 @Repository 어노테이션을 사용하여 표현한다. @Repository 어노테이션은 @Service 어노테이션과 같이 기본 Component 를 어노테이션으로 가지고 있어서 Spring Context 에 자동으로 등록된다. 주로 서비스 레이어에서 레포지토리 레이어에 접근하여 기능을 수행한다.
@Repository
public class UserRepository {
def findById(String id) {
// id 를 통해 User 를 찾는 로직
}
// ...
}
3. Model
Model 은 Controller 에서 View 로 넘겨주는 데이터로 View 에 렌더링할 정보를 가지고 있다. 애플리케이션의 기능에 따라 내부적으로 데이터를 처리하거나 출력하는 로직을 가지고 있다. Controller 에서는 사용자의 요청에 따라 Service, Repository 레이어 등을 통해서 정보를 획득하고 필요한 정보를 Model 에 담아서 전달한다. Model 은 단순 데이터 구조로 View 나 Controller 에 대한 정보는 알 수 없어야 한다.
4. View
View 는 MVC 에서 사용자에게 보여지는 화면이다. 해당 화면을 통해서 사용자의 동작에 따른 인터페이스를 수행한다. 사용자가 화면에서 수행하는 동작에 따라서 요청을 발생시키는 로직을 구현하고 이에 대한 결과를 화면에 출력해야 한다. 모든 데이터는 Model 에게서 가져와야 하고 View 가 이를 저장하고 있으면 안된다.
Spring MVC 에서는 View Resolver 를 통해서 Controller 에서 반환한 view 이름과 model 객체를 특정 view 페이지에 model 객체를 적용해서 반환한다.
[Reference]
- https://catsbi.oopy.io/441b4af6-e877-4dc5-9695-2983bbe22799#6b87f9a8-cd99-4910-8f64-fadbe4cf193c
'Tech > Spring | SpringBoot' 카테고리의 다른 글
[SpringBoot] Database 연동 - 2 (JDBC) (0) | 2022.09.17 |
---|---|
[SpringBoot] Database 연동 - 1 (DataSource, h2 database) (0) | 2022.09.13 |
[Spring] @Controller vs @RestController (0) | 2022.08.30 |
[Spring] Swagger 3.0.0 적용 (0) | 2022.07.01 |
[Spring] Spring Framework 개념 정리 (0) | 2021.05.05 |