
3계층 아키텍처(3-Layered Architecture)는 관심사의 분리(Separation of Concern) 원칙을 적용하여 유지보수성과 테스트 용이성을 높이는 설계 방식
웹 애플리케이션을 3개의 주요 계층으로 나누어 역할을 분리
| 계층 | 역할 | 주요 애너테이션 |
|---|---|---|
| Presentation Layer | 클라이언트 요청 처리, 응답 반환 (Spring MVC 컨트롤러) | @Controller |
| Business Layer | 비즈니스 로직 수행, Model에 데이터 생성 | @Service |
| Data Access Layer | 데이터베이스와 직접 연결, CRUD 처리 | @Repository |
@Controller를 사용@Controller
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}
}
@Controller → 이 클래스가 클라이언트 요청을 처리함@GetMapping("/{id}") → URL 요청을 받아 Service 계층 호출Controller에서 받은 요청을 처리하고 Repository 계층과 연결@Service를 사용@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserDTO getUserById(Long id) {
User user = userRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
return new UserDTO(user.getId(), user.getName());
}
}
@Service → 비즈니스 로직을 수행하는 클래스userRepository.findById(id) → DB에서 데이터를 가져옴@Repository를 사용@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findById(Long id);
}
@Repository → DB와의 직접적인 상호작용을 담당JpaRepository 상속 → 기본적인 CRUD 기능 제공public interface UserDao {
void create(User user);
User read(Long id);
void update(User user);
void delete(Long id);
}
JpaRepository를 상속받아 기본 CRUD 기능을 제공받음public interface UserRepository {
User get(Long id); // 원하는 기능만 구현
}
| DAO | Repository | |
|---|---|---|
| 개념 | DB에 직접 연결하여 CRUD 수행 | DAO를 감싸는 추상화 계층 |
| 특징 | SQL을 직접 다룸 | JPA, Hibernate 등을 활용 |
| 사용 방식 | JDBC, MyBatis 기반 | Spring Data JPA 기반 |
@Repository와 DAO 이 두 개념은 다르나, Spring에서 혼용해서 쓰기도 한다.
getter, setter 포함public class UserDTO {
private Long id;
private String name;
// 생성자, Getter, Setter
}
setter가 없으며 한 번 생성된 값은 변경 불가능public class UserVO {
private final Long id;
private final String name;
public UserVO(Long id, String name) {
this.id = id;
this.name = name;
}
// Getter만 제공 (Setter 없음)
}
| DTO | VO | |
|---|---|---|
| 변경 가능 여부 | 가변 (Mutable) | 불변 (Immutable) |
| 역할 | 데이터 전송 | 값 객체 (불변성 보장) |
회원 관리,상품 관리,결제 서비스가 하나의 서버에서 실행됨.
회원 관리 기능을 수정하려면 전체 애플리케이션을 다시 빌드하고 배포해야 함.
클라이언트 → API Gateway → 여러 개의 Microservices → 각각의 DB
Swagger 등을 사용하여 API 문서화Spring은 기존 모놀리식 아키텍처의 단점을 해결하고 유지보수성과 확장성을 높이는 환경을 제공
Spring Boot는 내장 웹 서버(Tomcat)를 포함하여 마이크로서비스를 손쉽게 실행 가능
Spring Cloud는 MSA에서 필요한 API Gateway, 서비스 등록/탐색, 분산 트랜잭션 관리 등을 지원
Spring을 사용하면 각 기능을 독립적인 서비스로 분리하고 확장하기 쉬움
| Spring 기능 | MSA에서의 역할 |
|---|---|
| Spring Boot | 독립적인 마이크로서비스 실행 가능 |
| Spring Cloud | MSA 환경에서 서비스 간 통신 및 로드 밸런싱 제공 |
| Spring Security | 개별 마이크로서비스 보안 관리 |
| Spring Data JPA | 각 마이크로서비스의 독립적인 DB 접근 용이 |