Spring MVC에서의 3계층 : Controller , Service , Repository

TopOfTheHead·2025년 10월 20일

Spring Boot

목록 보기
11/25
post-thumbnail

레이어드 아키텍처 레이어드 아키텍처
。각 계층독립적인 특정기능을 집중해서 수행하도록 관리하는 방식
SRP 준수

。각 계층고수준 상위계층으로부터 저수준 하위계층으로 단방향 의존성을 가지며 상호작용을 수행
저수준 계층에서 고수준 계층으로 의존성을 가지면 안된다.
추상화를 통해 상위계층하위계층의 세부사항을 알지 못해도 기능을 활용가능

Spring MVC 원리

보라색 : 개발자가 작성하는 logic
파란색 : 스프링이 처리하는 logic
개발자Controller , Service , Repository 역할의 Class를 집중해서 개발

Controller / Service / Repository Layer
Spring WebSpring MVC 디자인패턴에서 Dispatcher Servlet에서 HandlerAdapter를 통해 전달된 클라이언트의 실질적인 요청을 처리하는 3계층

。한 책임을 구현 시 Controller , Service , Repository 로 분할하여 구현
▶ 각각의 기능을 수정하더라도 다른 Layer에는 영향이 없어야하며 유지보수성 증진
관례프로젝트 내에서 각각의 Controller , Service , Repository , DTO 종류에 따라 패키지도 구별해서 분류해야함.

레이어드 아키텍처에 따라 각각 요청 처리 , Business Logic , DB 상호작용에 대한 기능을 독립적으로 구현하며 단방향 의존성을 준수해야한다.
클라이언트요청레이어드 아키텍처를 통한 Controller -> Service -> Repository 순서로 단방향 의존

실제 지라를 통해 어플리케이션개발시에도 저수준 클래스 -> 고수준 클래스 순서로 개발
repository -> service -> repository 순서로 개발
고수준 모듈을 개발 후 저수준 모듈을 개발 시 이를 의존하는 고수준 모듈도 함께 고려해야하므로 유지보수가 좋지않다.

Controller Layer
Dispatcher Servlet에서 전달받은 요청을 처리 및 응답하는 @RequestMapping, @GetMapping, ... 이 선언된 method
@Controller 클래스 내 포함

Controller는 기능분리를 통해 요청응답, 그리고 어떤 Service를 사용할 건지에 대해서만 담당하여 집중

레이어드 아키텍처Presentation Layer에 대응
▶ 다음 저수준 클래스Service Class를 의존
클래스Service 클래스 객체필드로 선언 및 의존성주입요청을 전달

Service Layer :
Controller에게 전달된 요청을 처리하는 Business logic을 작성하는 클래스

。주로 검증로직등을 작성

。각 Service Class인터페이스를 상속하여 Controller에서 사용하는 Service를 변경하더라도 Service 클래스 내에서 코드수정이 발생하지않도록 함
OCP 준수

MVCBusiness Logic 작성 및 어떤 Repository를 선택하여 데이터를 상호작용할지 정의

레이어드 아키텍처Business Layer에 대응
▶ 다음 저수준 클래스Repository Class를 의존
클래스Repository 클래스 객체필드로 선언 및 의존성주입요청을 전달

@Service를 선언하여 Spring Bean으로 등록

  • @Service Class는 각 Service Logic추상화Interface를 우선적으로 정의한 후 구현하는 방식을 권고
    Member 기능 구현 시 각 Service Logic을 추상화한 MemberService 인터페이스와 해당 인터페이스를 구현한 MemberServiceImpl 클래스를 각각 생성

    。 단 Interface구현 클래스가 하나밖에없는 경우 관습적 추상화가 되나 이건 본인의 취향에 따라 결정.
    관습적 추상화 : 관례를 지키고자 불필요한 추상화를 수행하는 것

    인터페이스
public interface MemberService {
	void createMember(MemberCreateRequest memberCreateRequest);
}

구현 @Service 클래스

@RequiredArgsConstructor
@Service
public class MemberServiceImpl implements MemberService {
	private final MemberRepository memberRepository;
	@Override
	@Transactional
	public void createMember(MemberCreateRequest request){
		//
	}
}

Repository Layer
DB와의 상호작용을 담당하는 Repository Class
DAO(Data Access Obejct) 역할을 수행하는 클래스

레이어드 아키텍처Persistence Layer에 대응
실제 DB를 의존하여 연결됨
▶ 단 JdbcJPA 사용 시 해당 구현체( ex. JdbcTemplate , ...)를 필드로 선언하여 의존성주입하여 DB와 상호작용하여 사용

@Repository를 선언하여 Spring Bean으로 등록

JPA의 경우 해당 RepositoryJpaRepository 인터페이스를 확장한 인터페이스로 대체

실습

패키지별로 구분

  • Controller
@Controller
@ResponseBody
public class CourseController {
	private CourseService courseService;
	// 요청, 응답 역할을 수행하는 Controller
	// 가장 고수준으로서 Service를 의존
	@RequestMapping("/add-course")
	public void addCourse(){
		// Service에 정의된 Business Logic 수행
		courseService.insertCourses();	
	}
}
  • Service
// Business Logic 을 수행하는 Service 클래스
// 저수준인 Repository 클래스 의존
@Service
@RequiredArgsConstructor
public class CourseService {
	private CourseRepository courseRepository;
	public void insertCourses(){
		// Repository를 통해 DB에 접근
		courseRepository.insert(1,"수학");
		courseRepository.insert(2,"영어");
	}
}
  • Repository
// DB와 상호작용하는 Repository 클래스
// 가장 저수준이므로 의존하는 계층이 없다
@Repository
public class CourseRepository {
	JdbcTemplate jdbcTemplate; // JdbcTemplate 구현체 의존성주입
	private String insert_sql = """
		insert into course_table values(?,?);
		""";
	public  CourseRepository(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	// JDBC를 통해 DB랑 상호작용
	public void insert(int courseId, String courseName){
		jdbcTemplate.update(insert_sql, courseId,  courseName);
	}
}
profile
공부기록 블로그

0개의 댓글