Spring 아키텍처
Spring 아키텍처
Spring 아키텍처
Controller · Service · Repository · JPA · DTO · Entity
1. Controller
Controller는 클라이언트의 요청(URL) 을 받아 비즈니스 로직(Service) 을 호출하고
View 또는 데이터(JSON) 를 반환하는 역할을 담당
👉 요청 → 처리 흐름을 연결해주는 입구 역할
1-1. @Controller
- View(화면) 반환이 주 목적
- API와 View를 동시에 사용하는 경우에 사용
- 객체를 반환하려면
@ResponseBody를 명시적으로 사용
1
2
3
4
5
6
7
8
9
@Controller
public class SampleController {
@GetMapping("/test")
@ResponseBody
public String test() {
return "hello";
}
}
1-2. @RestController
- View가 필요 없는 API 전용 Controller
- Spring 4.0.1부터 제공
- 모든 메서드에
@ResponseBody가 자동 적용
1
2
3
4
5
6
7
8
@RestController
public class ApiController {
@GetMapping("/api/test")
public ResponseEntity<String> test() {
return ResponseEntity.ok("hello");
}
}
@RestController = @Controller + @ResponseBodyreturn : JSON / XML 등 데이터
2. Service 계층
Service는 비즈니스 로직을 담당하는 계층
- 여러 Repository 조합
- 트랜잭션 처리
- 도메인 로직 구현
2-1. Service Interface 와 Impl 을 나누는 이유
1. AOP (관점 지향 프로그래밍)
Spring AOP는 특정 메서드 호출 시점에 프록시 객체(Proxy Bean) 를 생성하여 트랜잭션, 로깅 같은 부가 기능을 수행
프록시 생성 방식은 크게 두 가지
| 구분 | 설명 |
|---|---|
| JDK Dynamic Proxy | 인터페이스 필수 |
| CGLIB | 클래스 기반 프록시 |
과거 CGLIB의 문제점
- 별도 의존성 필요
- 기본 생성자 필수
- 생성자 2번 호출
이로 인해 과거에는 JDK Dynamic Proxy 권장
현재 Spring Boot
- Spring 3.2 이후 CGLIB 문제점 개선
- Spring Boot 기본 설정
1
spring.aop.proxy-target-class=true
- 인터페이스가 있어도 CGLIB 사용
- 성능도 JDK Proxy보다 우수
1
2
3
4
5
# JDK Dynamic Proxy 사용
spring.aop.proxy-target-class=false
# CGLIB 사용 (기본값)
spring.aop.proxy-target-class=true
2. OOP (객체지향 설계)
Service를 인터페이스로 분리했을 때 장점 :
- 구현체 변경에 유연
- 결합도 감소
- 다형성 활용 가능
OCP (개방-폐쇄 원칙)
- 기존 코드는 변경하지 않고
- 기능 확장은 가능해야 한다
DIP (의존관계 역전 원칙)
- 구현 클래스 ❌
- 추상화(인터페이스)에 의존 ⭕
언제 나누는 것이 좋을까?
- 구현체가 2개 이상 존재할 가능성이 있을 때
- ex) 카드 결제
- 결제
- 취소
- 부분 취소 등
3. 트랜잭션(Transaction)
트랜잭션이란 db 상태를 변경하는 하나의 논리적 작업 단위
- 모두 성공하거나
- 하나라도 실패하면 전체 롤백
트랜잭션의 특징
- 작업의 완전성 보장
- 일부만 반영되는 현상 방지
- DB 관점에서는 CRUD 단위
Spring의 트랜잭션 처리 방식
Spring에서는 선언적 트랜잭션을 주로 사용
1
2
3
4
@Transactional
public void save() {
...
}
@Transactional적용 시 프록시 객체 생성PlatformTransactionManager가 트랜잭션 제어- 정상 : Commit
- 예외 : Rollback
트랜잭션은 어디에 적용해야 할까?
❌ Controller
❌ Repository
⭕ Service 계층
이유:
- 여러 Repository 조합
- 비즈니스 단위 처리
참고로 트랜잭션에 대해 잘 정리된 글이 있어서 링크 첨부한다.
[Java]@Transactional Annotation 알고 쓰자
4. Repository 계층
Repository는 Entity를 통해 DB 테이블에 접근하는 계층
- CRUD 처리
- DB 접근 코드 담당
5. Spring Data JPA
JPA란?
- Java Persistence API
- ORM 기술 표준
- 객체 ↔ 관계형 DB 간 차이 해결
구조 :
1
2
3
4
5
6
7
8
9
Application
↓
JPA
↓
Hibernate
↓
JDBC
↓
DB
Hibernate
- JPA 구현체 중 가장 대표적
- EntityManager 등 JPA 인터페이스 구현
Spring Data JPA
- JPA를 한 번 더 추상화
- Repository 인터페이스 제공
- CRUD 메서드 자동 제공
1
2
3
public interface RegistryRepository
extends JpaRepository<Registry, Long> {
}
<Entity, PK 타입>지정 필수@Repository생략 가능
정리
- JPA: ORM 기술 명세
- Hibernate: JPA 구현체
- Spring Data JPA: Repository 제공 프레임워크
6. DTO · Entity · Repository
DTO (Data Transfer Object)
- 순수 데이터 객체
- getter / setter 만 존재
- 계층 간 데이터 전달 목적
VO는 DTO와 유사하지만 Read Only
Entity
- DB 테이블과 1:1 매핑
@Entity필수- JPA 관리 대상
계층 흐름
1
2
3
4
5
6
7
8
9
Client
↔ DTO
Controller
↔ DTO
Service
↔ DTO
Repository
↔ Entity
DB
7. DAO · Model (JPA 미사용 시)
- JPA 미사용 환경
- MyBatis 등 사용
DAO
- DB 접근 객체
- Service ↔ DB 연결 역할
@Repository사용
1
2
3
4
5
<mapper namespace="project.dao.SampleDAO">
<select id="methodName" resultType="">
SELECT ...
</select>
</mapper>
흐름
1
2
3
4
5
Client
↔ Controller
↔ Service
↔ DAO
↔ DB
REFERENCE
This post is licensed under CC BY 4.0 by the author.
