SpringBoot/서비스 계층 및 비즈니스 로직
서비스 계층 생성 및 역할
by DEVLIB
2025. 4. 15.
MVC 3계층 구조 이해
계층
|
설명 |
Controller |
사용자 요청/응답 처리 (API 진입점) |
Service |
비즈니스 로직을 담당 (주 로직 중심) |
Repository |
데이터 저장소(DB)와 직접 통신 |
서비스 계층은 도메인 로직의 중심입니다.
단순히 DB에 넘겨주는 수준을 넘어서서, 다양한 검증·처리·계산이 포함됩니다.
서비스 계층 생성 예시
1. 기본 구조
@Service
public class MemberService {
private final MemberRepository memberRepository;
// 생성자 주입 (추천 방식)
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 비즈니스 로직 예시
public Member register(String name, String email) {
if (memberRepository.existsByEmail(email)) {
throw new IllegalArgumentException("이미 존재하는 이메일입니다.");
}
Member member = new Member(name, email);
return memberRepository.save(member);
}
public Member getByEmail(String email) {
return memberRepository.findByEmail(email)
.orElseThrow(() -> new NoSuchElementException("회원 없음"));
}
}
@Service 애너테이션의 의미
- 스프링이 이 클래스를 서비스 빈으로 등록해줍니다.
- @Component의 세부 확장형이므로, 스프링 컨테이너가 자동 관리
- 의존성 주입(Dependency Injection)을 받을 수 있음
서비스 계층의 역할 정리
역할 |
상세 설명 |
비즈니스 로직 처리 |
핵심 기능: 가입, 결제, 인증 등 도메인 로직 구현 |
트랜잭션 관리 |
@Transactional로 원자적 처리 보장 |
검증 및 예외 처리 |
입력값 검증, 조건 체크, 에러 대응 등 |
복합 로직 구성 |
여러 Repository를 함께 호출하거나 데이터 가공 |
Controller/Repository 중간 계층 역할 |
요청 흐름을 제어하는 구조적 완충지 |
Controller와 함께 사용하는 흐름 예시
@RestController
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@PostMapping("/members")
public ResponseEntity<?> register(@RequestBody MemberDto dto) {
try {
Member member = memberService.register(dto.getName(), dto.getEmail());
return ResponseEntity.ok(member);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
}
}
실무 팁
- 서비스 계층은 항상 Repository에 바로 의존하고, 컨트롤러는 Repository에 직접 접근하지 않도록 설계
- 공통 로직(로그인, 유효성 검사 등)은 별도 유틸/컴포넌트 계층으로 분리해도 좋음
- 서비스 내부에서는 엔티티를 그대로 사용하지 않고 DTO 변환도 함께 고려
마무리 요약
항목 |
설명 |
@Service |
비즈니스 로직을 담는 계층에 사용 |
주 역할 |
핵심 처리, 검증, 트랜잭션 등 |
의존성 구조 |
Controller → Service → Repository |
설계 이점 |
코드 분리, 유지보수 ↑, 테스트 용이성 ↑ |