프레임워크 (Framework)
- 소프트웨어 개발을 간편하게 하기 위한 소프트웨어 개발 환경이다.
- 장점
- 기본적으로 필요한 기능과 도구를 제공해 개발자들이 핵심 비즈니스 로직에만 집중할 수 있다.
- 일관된 구조를 제공해 코드의 일관성과 가독성을 높혀 팀 협업이 편해진다.
- 보안 관련 기능을 기본적으로 제공해 보안 취약점을 방지한다.
- 단점
- 복잡한 구조를 가지고 있어 처음 익히는데 시간이 많이 소요된다.
- 프레임워크의 새로운 버전이 기존 코드와 호환되지 않을 수 있다.
- 정해진 규칙과 구조를 강제해 자유롭지 않다.
라이브러리
- 개발에 필요한 클래스, 함수 등을 모아둔 코드의 모음을 뜻하며, 개발자들이 필요에 따라 원하는 기능을 가져다 쓸 수 있다.
- 장점
- 개발자가 복잡한 코드를 직접 작성하지 않아 개발 생산성이 높아진다.
- 검증된 라이브러리는 테스트와 커뮤니티 지원을 통해 안정성과 품질을 보장한다.
- 단점
- 버전 호환성 문제로 다른 라이브러리나 기존 코드와 충돌이 발생할 수 있다.
- 내부 구현을 직접 수정하기 어려워, 우리가 원하는대로 수정하기 힘들 수 있다.
프레임워크와 라이브러리 구조

어노테이션 (Annotation)
- 코드에 메타 데이터를 추가할 수 있는 기능을 제공
- 컴파일러나 런타임에 특정 동작을 트리거하기 위해 사용
- 특정 코드를 사용하는 프로그램에게 정보를 전달하기 위해 사용
- @기호로 시작하며 변수, 메서드, 클래스, 패키지, 매개변수 등에 추가 가능
- 내장 어노테이션
@Override
- 상위 클래스나 인터페이스 메서드를 오버라이드 하고 있는지 나타낸다.
- 이 때 컴파일러는 실제로 오버라이드 하는지 확인한다.
@Deprecated
- 해당 요소가 더 이상 사용되지 않음을 나타낸다.
- 해당 어노테이션이 붙은 코드를 사용하면 컴파일 경고가 발생
- 사용자 정의 어노테이션
- 개발자가 필요에 따라 직접 어노테이션을 정의할 수 있다.
- 특정 메타데이터를 추가하거나, AOP와 같은 기술과 결합해 다양한 기능을 구현할 수 있다.
Template Engine
- 동적인 웹페이지를 생성하기 위한 도구이며, 템플릿을 이용해 정적인 부분과 동적인 부분을 결합해 문서를 생성하는 역할
- UI (User Inteface)를 만들며, SSR (Server Side Rendering)에 사용된다.
- 템플릿 엔진이 나온 이유
- 자바 코드로 HTML을 만들어 내는 것이 아닌 HTML 문서에 동적으로 변경해야 하는 부분만 자바 코드를 넣을 수 있다면 더 편리하다.
- 대표적인 템플릿 엔진
- Thymeleaf
- Spring과 통합이 잘 되어있다.
- 다양한 기능을 포함하고 있다. (개발할 때 더 쉽게 해줌)
- JSP (Java Server Page)
- 현재 잘 안쓰는 추세이다.
Servlet과 JSP의 구조

MVC 패턴
- 하나의 Servlet이나 JSP로 처리하던 것을 Model, View, Controller로 나눈 것이다.
- 핵심 내용
- 비즈니스 로직과 View의 완전한 독립적인 분리
- 두 연관 없는 코드끼리 같이 있을 필요가 없기 때문이다.
- MVC 패턴 구조
- Controller
- HTTP Request를 전달받아 파라미터를 검증한다.
- 비즈니스 로직을 실행한다.
- 비즈니스 로직을 Service Layer로 만들어 처리한다.
- Database와 상호작용하는 Repository Layer를 추가로 구성한다.
- 비즈니스 로직을 처리한 Database 조회 결과를 Model에 전달한다.
- Model
- View에 출력할 데이터를 임시 저장하는 객체
- View가 화면을 띄워야 될 때 Model에서 해당 데이터를 참조해 사용한다.
- View
- Model에 담겨있는 데이터를 사용해 화면을 Rendering 한다.
- 동적으로 변경된 HTML을 완성시켜 클라이언트에게 응답한다.
MVC 패턴의 문제점
dispatcher.forward(request, response)View로 이동하는 forward가 중복 호출된다.
String path = “/WEB-INF/views/new-form.jsp”View의 path를 입력(중복 작업) 한다.
- jsp의 확장자가 바뀐다면 모든 코드에서 path의 확장자를 수정해야함
HttpServletResponse객체를 사용하는 경우가 너무 적다.
- JSP에서 모두 해결하기 때문
- 공통 기능이 추가될수록 Controller에서 할 일이 너무 많아진다.
- 공통 기능 처리 : 모든 Controller에서 공통으로 적용되는 기능
- ex) Log출력, 인증(로그인), 인가(권한) 등
- 이를 위해 고안해낸 프론트 컨트롤러 패턴
프론트 컨트롤러 패턴
- Controller들이 호출되기 전 하나의 Servlet에서 공통 기능을 처리해주는 패턴
- 프론트 컨트롤러 (Servlet)에서 공통 기능을 처리하면 된다.
- 프론트 컨트롤러 구조
- 프론트 컨트롤러 패턴 역할
- 모든 요청을 하나의 프론트 컨트롤러가 받아 공통 기능을 처리한다.
- 해당 요청을 처리할 수 있는 Controller를 호출한다. (Controller Mapping)
- 프론트 컨트롤러를 제외한 나머지 Controller들은 Servlet을 사용하지 않아도 된다.
- 프론트 컨트롤러 패턴 의문점
- 위 그림처럼 공통 처리를 하려면 모든 컨트롤러의 반환 값이 같아야 함
- 당연히 모든 컨트롤러마다 결과가 다를테고 억지로 맞추려고 하면 애플리케이션의 확장성이 떨어짐
- 이를 위해 고안해낸 어댑터 패턴
어댑터 패턴
- 다양한 컨트롤러를 유연하게 만들기 위함
- 서로 다른 인터페이스를 갖는 두 클래스를 연결해주는 패턴
- 어댑터 패턴 구조 (여기서 Handler는 Controller를 의미)
- 컨트롤러는 비즈니스 로직을 처리하고 결과를 반환
- 어댑터는 컨트롤러와 공통 로직이 자연스럽게 연결되도록 함
- 어댑터 패턴 장점
- 프론트 컨트롤러, 어댑터, 컨트롤러 모두 각자의 역할만 수행한다.
- 새로운 컨트롤러가 추가되어도 어댑터와 컨트롤러만 추가하면 공통 로직을 변경할 필요가 없다.
Spring MVC
- MVC 패턴에 프론트 컨트롤러 패턴 + 어댑터 패턴 적용
- Spring MVC 패턴 구조
Dispatcher Servlet: Spring의 프론트 컨트롤러View: 인터페이스로 구성돼있고, 확장성을 가짐
- 실행 순서
- 클라이언트로 부터 HTTP Request를 받는다.
- 핸들러 조회 (Handler Mapping을 통해 알맞은 핸들러 조회)
- 핸들러를 처리할 어댑터 조회
- 핸들러 어댑터를 실행 (알맞은 어댑터가 있다면 요청을 위임함)
- 핸들러 실행 (핸들러 어댑터가 핸들러를 호출해 실행 및 결과 반환)
- Model And View 반환 (핸들러의 반환 정보를 해당 객체로 변환해 반환)
- viewResolver 호출 (알맞은 View 요청)
- View 반환 (viewResolver는 랜더링 역할을 담당하는 View 객체를 반환)
- View Rendering (View를 통해 랜더링)
- 요약
Dispatcher Sevlet
- HTTP Request를 알맞게 파싱하고, 클라이언트에게 알맞은 응답을 반환
- 핸들러 목록 정보를 알고있음
- 핸들러 어댑터 목록 정보를 알고있음
Handler Adapter
- 자신이 처리할 수 있는 핸들러인지 확인하는 메서드 필요
- 프론트 컨트롤러부터 요청을 위임 받았을 때 핸들러에게 요청을 지시하는 기능이 필요
- 반환시 핸들러로부터 받은 결과를 알맞은 응답으로 변환
Handler
- 요청에 대한 로직을 수행하는 기능이 필요