SMHRD · Spring Framework

Spring 기초

코드를 외우는 대신 데이터가 어디로 흐르는지 그림으로 익힙니다. 한 번 만든 기능을 다시 만들면서 더 깔끔하게 — 마지막에는 REST API 게시판 한 채를 직접 짓습니다.

개념 실습 전환점 마일스톤
PART · WEB

웹의 동작 원리

클라이언트 · 서버 · HTTP
클라이언트와 서버
네트워크 / 클라이언트 / 서버
매일 보는 웹사이트는 누가 누구에게 무엇을 부탁하는 일인가. 요청과 응답의 가장 기본 단위.
HTTP 해부
F12로 보는 진짜 HTTP
크롬 개발자 도구로 실제 요청·응답 메시지를 한 줄씩 뜯어본다. 헤더·바디·상태 코드가 무엇을 하는지.
GET vs POST
URL 에 적느냐, 바디에 숨기느냐
같은 폼을 GET 과 POST 로 각각 보내며, 어디에 데이터가 실리는지 눈으로 확인.
무상태성과 쿠키·세션
서버가 사용자를 기억하지 못하는 이유
HTTP 가 왜 기억을 못 하는지, 그래서 어떤 도구가 등장했는지 (개념만 살짝).
정적 vs 동적 / WAS
정적 페이지와 동적 페이지의 차이
같은 HTML 인데 어떨 때 매번 다르게 보일까. 웹서버와 WAS(Tomcat)의 분업.
Hello Servlet v0
브라우저에 내 응답이 처음 뜬다
Tomcat 위에 Servlet 한 개를 올리고, 브라우저로 첫 응답을 받아본다. 우리 프로젝트의 v0 시작점.
PART · SPRING

Java와 Spring의 철학

JVM · 객체 지향 · IoC / DI
JVM 한눈에
컴파일·로더·실행엔진·GC
자바가 어떻게 OS 위에서 돌아가는지를 한 번에. 깊이 들어가지 않고 그림으로.
Call by Value
참조형도 「값」을 복사한다
메서드 안에서 객체를 바꿨는데 원본이 안 바뀌는, 또는 그 반대인 경우를 코드로 뜯어본다.
클래스 vs 인스턴스
객체가 메모리에 만들어지는 방식
클래스 한 개로 인스턴스 여러 개가 어떻게 찍혀 나오는지. 각 인스턴스가 가지는 독립된 데이터.
new의 함정
강한 결합을 손으로 느껴본다
DI 를 배우기 전에, 일부러 new 로 결합한 코드를 써보고 부품 하나 바꿀 때 무엇이 부서지는지 체감.
IoC — 제어 역전
제어권은 누구에게 있는가
객체 생성·소멸의 권한이 개발자에서 컨테이너로 넘어간다. 그게 왜 좋은지를 코드로 본다.
DI — 의존성 주입과 @Autowired
전 차시의 코드를 다시 쓴다
「new 의 함정」에서 짠 코드를 DI 로 다시 짜며 결합도가 어떻게 풀리는지 Before/After 로.
Spring vs Spring Boot
우리는 왜 Legacy 로 시작하는가
자동 설정과 내장 서버를 제공하는 Boot 의 편리함과, 우리가 굳이 XML 부터 보는 이유.
Maven & pom.xml
의존성 관리의 작동 원리
의존성 한 줄을 추가하면 어디에 무엇이 다운로드되는지. Maven Update 누락의 함정.
개발 환경 구축
Eclipse + STS + Tomcat 연동
실제로 손가락이 움직이는 환경 만들기. 끝까지 따라가면 첫 빨간 줄이 사라진다.
첫 Spring 프로젝트 + Bean 주입
흐름도에 첫 박스를 그린다
Spring Legacy Project 를 만들고, Bean 한 개를 컨테이너에 등록한 뒤 주입받아본다.
PART · MVC

Spring MVC 아키텍처

계층 분리 · DispatcherServlet · 설정 파일
MVC — 왜 분업하나
역할 분리가 만드는 유연성
분리된 역할이 왜 유연성을 만드는지. 한 덩어리 코드와의 비교.
6개 계층 한눈에
DispatcherServlet ~ View 한 번에
요청 진입점부터 응답 화면까지 6개 계층의 책임을 한 그림으로 정리한다.
DispatcherServlet 깊이 보기
URL 분배 로직
URL 을 받아 어떻게 적절한 Controller 에게 넘기는지 — HandlerMapping 까지 살짝.
Controller 해부
@RequestMapping · 파라미터 · Model
컨트롤러 메서드 한 개를 라인별로 뜯어보며 파라미터가 어떻게 들어오고 모델이 어떻게 나가는지.
Service 계층
비즈니스 로직과 트랜잭션 자리
왜 컨트롤러에 SQL 을 쓰면 안 되는가. 셰프의 조리법이 사는 곳.
DAO / Repository
SQL 만 책임지는 계층
창고 관리자의 일은 식재료를 꺼내는 것뿐. 데이터 접근의 책임을 한곳에 몰아둔다.
DTO · VO · Model
세 객체의 역할과 차이
셋이 비슷해 보이지만 어디에서 어디로 데이터를 옮기는지가 다르다. 실제 코드로 비교.
View · ViewResolver
JSP 가 어디 있는지 어떻게 알까
컨트롤러가 반환한 문자열이 어떻게 진짜 JSP 파일로 매핑되는지.
설정 파일 3종 해부
XML 공포증 해소 차시
web.xml · root-context.xml · servlet-context.xml 을 한 줄씩 읽으며 무엇이 무엇에 영향을 주는지.
한글 깨짐 필터
학생이 가장 먼저 만나는 「??? 글자」
CharacterEncodingFilter 한 줄이 어떻게 깨진 글자를 살리는지.
첫 종단간 흐름 v0.5
DB 없이 끝까지 데이터를 흘려본다
폼 → Controller → Service → (하드코딩 데이터) → JSP. 흐름도가 처음 한 줄로 이어진다.
PART · DB

데이터와 MyBatis

SQL · MyBatis · 트랜잭션
DB 기초
테이블 · 행 · 열 · PK · FK
DB 는 친숙한 「엑셀 시트」다. 가장 적은 단어로 가장 많은 그림을 그린다.
SQL 핵심 4종
SELECT · INSERT · UPDATE · DELETE
실무의 80% 를 차지하는 네 가지 쿼리만 끝까지. 그 외는 필요할 때 검색해도 늦지 않다.
MySQL 설치 + 테이블 만들기
회원·게시판 테이블 직접 작성
DDL 을 손으로 쳐서 테이블을 만든다. 이 테이블이 과정 끝까지 우리와 함께 간다.
JDBC → MyBatis
Before / After 코드를 나란히
JDBC 의 길고 반복적인 코드를 MyBatis 가 어떻게 줄여주는지. 학생이 「이래서 쓰는구나」를 납득한다.
DB 붙이려면 어디를 손대나
5단계 설정 변경 지도
① pom.xml ② root-context.xml ③ mybatis-config.xml ④ Mapper(인터페이스+XML) ⑤ Service 주입. 디버깅 첫 점검표.
HikariCP 커넥션 풀
왜 풀(Pool)이 필요한가
매번 새 DB 연결을 만들지 않고 미리 만들어둔 연결을 꺼내 쓰는 이유와 효과.
Mapper 인터페이스 ↔ XML
두 파일이 어떻게 짝지어지는가
namespace 와 id 가 만나는 순간을 직접 확인. 이름 한 글자 틀리면 무엇이 일어나는지.
카멜 ↔ 스네이크 함정
데이터가 null 이 되는 가장 흔한 이유
userId vs user_id. 일부러 깨뜨려보고 두 가지 해법으로 고친다.
SQL 인젝션 직접 시연
#{} vs ${}
위험한 코드를 일부러 만들어 공격해보고, 안전한 코드로 다시 쓴다.
@Transactional 기본
전부 성공하거나 전부 취소
트랜잭션이 무엇을 약속하는지. 깊이 들어가지 않고 「하나라도 실패하면 되돌린다」는 감각만.
첫 DB 종단간 v1
회원 한 줄을 DB 에서 꺼내 화면으로
v0.5 의 하드코딩 자리에 DB 를 끼워 넣는다. 흐름도가 처음 끝에서 끝까지 연결된다.
PART · BOARD

회원과 게시판

인증 · 세션 · CRUD · 인가
회원가입 폼 — name 속성과 VO 필드 매칭
JSP 폼이 서버 객체로 자동 바인딩되는 원리
`<input name="id">` 의 name 속성이 Member VO 의 필드명과 일치하면 — Spring 이 알아서 `Member.setId(...)` 를 호출. 이 매칭이 어긋나면 어떻게 되는지도 직접 확인.
원시적인 회원가입/로그인 v2
평문 저장 + 세션 없음 (일부러)
의도적으로 안전하지 않게 만들어보고 「페이지 이동하면 로그인이 풀리네?」를 직접 체감한다.
쿠키 깊이 보기
브라우저 쪽에 저장됨
F12 Application 탭에서 직접 본다. 만료 · 도메인 · HttpOnly 옵션이 무엇인지.
세션 깊이 보기
서버 쪽에 저장됨 + JSESSIONID
세션 저장소가 어디에 있고, 무엇이 매개하는지. 「손목 도장」의 진짜 정체.
쿠키 vs 세션
무엇을 어디에 저장할 것인가
두 도구의 저장 위치 차이를 의사결정 기준으로 정리. 비밀번호는 어디에 저장하면 안 되는가.
안전한 회원가입/로그인 v3
BCrypt + 세션 도입
v2 의 두 가지 문제(평문 / 무상태)를 해결. v2 와 코드 차이를 한 줄씩 비교한다.
깔끔한 로그인 v4
인터셉터 + 공통 레이아웃
v3 컨트롤러에 박혀있던 if(session==null) 들이 사라진다. 헤더에서 로그인 상태를 표시.
최소 게시판 v5
Create + Read 만 (인가 없음)
「누구나 남의 글을 수정할 수 있는 위험한 게시판」으로 의도적으로 둠. 다음 차시의 동기.
안전한 게시판 v6
Update / Delete + 본인 확인
v5 의 인가 부재를 해결. 작성자 = 세션 사용자 비교 한 줄이 어디에 들어가는지.
페이징 게시판 v7
대용량 대비 (보강)
글 100개를 INSERT 한 뒤 화면이 망가지는 걸 직접 보고, 페이징으로 해결한다.
팀 분업 시뮬레이션
같은 데이터 이름으로 만나는 세 트랙
팀 프로젝트의 출발선. View · Controller · Mapper 트랙이 같은 필드명을 약속하고 합류하는 과정을 모의 진행한다.
PART · REST

REST API와 마무리

비동기 통신 · JSON · 디버깅
비동기 통신이 푼 문제
전체 새로고침 vs 부분 통신
댓글 하나 달 때마다 전체 페이지가 깜빡이던 시절을 시연. Ajax 가 무엇을 풀어주는지.
JSON 형식 깊이
그릇(DTO)이 JSON 으로 변환되는 순간
자바 객체와 JSON 문자열이 어디서 어떻게 만나는지. Jackson 의 자동 변환을 보면서.
@RestController
View 가 빠진 흐름도
@Controller 와 무엇이 다른가. 흐름도에서 「식탁」 박스가 사라지고 JSON 화살표가 등장.
HTTP 메서드 어노테이션
Get / Post / Put / Delete Mapping
URL 하나에 동작을 어떻게 분기시키는지. RESTful 한 URL 디자인의 첫걸음.
REST 컨트롤러로 변환 v8
v6 컨트롤러를 RestController 로
통째로 복사해서 옮겨쓰며 무엇이 사라지고 무엇이 남는지 확인. 첫 REST 게시판 등장.
비동기 댓글 v9
새로고침이 사라진다
fetch 로 댓글을 작성하고, JSON 응답을 받아 DOM 에 직접 그려넣는다.
자잘한 비동기 + 첨부파일 v10
조회수 즉시 증가 / MultipartResolver
v9 패턴을 응용하며 게시판을 풍성하게. 파일 업로드와 다운로드까지 마무리.
데이터 흐름 디버깅 워크숍 v∞
흐름도를 거꾸로 거슬러 올라간다
실제 버그 시나리오 5개를 ① F12 → ② 콘솔 → ③ Mapper SQL 로그 → ④ DB → ⑤ 응답 순서로 추적. 4주 학습의 마무리.

▼ TEST · 다음 과정 미리보기

SpringBoot 개요 — 테스트 링크