스프링은 한마디로
사용자의 요청을 받아서 DB와 연결해 데이터를 처리하고 다시 응답하는 구조
이 전체 흐름은 아래 3-Layer 구조로 움직인다.
1. 전체 구조 한눈에 보기

2. Controller (입구 / 안내 데스크)
Controller는 사용자의 HTTP 요청을 받는 입구
@RestController
@RequiredArgsConstructor
public class MemoController {
private final MemoService memoService;
@PostMapping("/memos")
public ResponseEntity<CreateMemoResponse> createMemo(@RequestBody CreateMemoRequest request) {
return ResponseEntity.status(HttpStatus.CREATED).body(memoService.save(request));
}
@GetMapping("/memos/{memoId}")
public ResponseEntity<GetMemoResponse> getOneMemo(@PathVariable Long memoId) {
return ResponseEntity.status(HttpStatus.OK).body(memoService.findOne(memoId));
}
@GetMapping("/memos")
public ResponseEntity<List<GetMemoResponse>> getAllMemos() {
return ResponseEntity.status(HttpStatus.OK).body(memoService.findAll());
}
@PatchMapping("/memos/{memoId}")
public ResponseEntity<UpdateMemoResponse> updateMemoContents(@PathVariable Long memoId, @RequestBody UpdateMemoRequest request) {
return ResponseEntity.status(HttpStatus.OK).body(memoService.update(memoId, request));
}
@DeleteMapping("/memos/{memoId}")
public ResponseEntity<Void> deleteMemo(@PathVariable Long memoId) {
memoService.delete(memoId);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
역할
- 요청 받기 (GET, POST, PUT, DELETE)
- DTO로 데이터 전달
- 응답 반환
핵심: 요청/응답만 담당, 로직은 없음
3. Service (업무 처리 담당)
Service는 실제 일을 하는 곳
@Service
@RequiredArgsConstructor
public class MemoService {
private final MemoRepository memoRepository;
@Transactional
public CreateMemoResponse save(CreateMemoRequest request) {
Memo memo = new Memo(request.getContents());
Memo savedMemo = memoRepository.save(memo);
return new CreateMemoResponse(savedMemo.getId(), savedMemo.getContents());
}
@Transactional(readOnly = true)
public GetMemoResponse findOne(Long memoId) {
Memo memo = memoRepository.findById(memoId).orElseThrow(
() -> new IllegalStateException("없는 메모입니다.")
);
return new GetMemoResponse(memo.getId(), memo.getContents());
}
@Transactional(readOnly = true)
public List<GetMemoResponse> findAll() {
List<Memo> memos = memoRepository.findAll();
List<GetMemoResponse> dtos = new ArrayList<>();
for (Memo memo : memos) {
GetMemoResponse dto = new GetMemoResponse(memo.getId(), memo.getContents());
dtos.add(dto);
}
return dtos;
}
@Transactional
public UpdateMemoResponse update(Long memoId, UpdateMemoRequest request) {
Memo memo = memoRepository.findById(memoId).orElseThrow(
() -> new IllegalStateException("없는 메모입니다.")
);
memo.updateContents(request.getContents());
return new UpdateMemoResponse(memo.getId(), memo.getContents());
}
@Transactional
public void delete(Long memoId) {
boolean existence = memoRepository.existsById(memoId);
if (!existence) {
throw new IllegalArgumentException("없는 메모입니다.");
}
// 존재하면
memoRepository.deleteById(memoId);
}
}
역할
- 비즈니스 로직 처리
- 데이터 가공
- 여러 Repository 조합 가능
핵심: 실제 서비스 로직이 있는 곳
4. Repository (DB 창고)
Repository는 DB랑 직접 연결되는 곳
public interface MemoRepository extends JpaRepository <Memo, Long> {
}
역할
- DB 저장
- DB 조회
- DB 삭제
핵심: DB랑 직접 대화하는 창고
5. Entity (DB 테이블과 연결된 객체)
Entity는 DB와 1:1로 연결되는 객체
@Getter
@Entity
@Table(name = "memos")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Memo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "contents", length = 255)
private String contents;
public Memo(String contents) {
this.contents = contents;
}
public void updateContents(String contents) {
this.contents = contents;
}
}
역할
- DB 테이블 구조 표현
- 실제 저장되는 데이터
핵심: DB의 한 행(Row)을 자바 객체로 표현한 것
6. DTO (데이터 전달 상자)
DTO는 사용자와 데이터를 주고받기 위한 객체다.
@Getter
public class CreateMemoResponse {
private final Long id;
private final String contents;
public CreateMemoResponse(Long id, String contents) {
this.id = id;
this.contents = contents;
}
}
역할
- 필요한 데이터만 전달
- Entity 직접 노출 방지
핵심: 데이터 전달용 전용 박스
'Spring' 카테고리의 다른 글
| [Spring] 핵심 개념 정리 (Bean, IoC, DI) (0) | 2026.07.02 |
|---|---|
| [Spring] Request DTO는 스프링이 만들어주는데, Response DTO는 왜 내가 만들어야 할까? (0) | 2026.07.01 |
| [Spring 입문] Servlet 이해하기 (0) | 2026.06.26 |
| [Spring 입문] 어노테이션 & Lombok (0) | 2026.06.25 |
| [Spring 기초] Spring이란? (0) | 2026.06.24 |