MVC(Model View Controller)
MVC안에 Spring web Layer를 넣으면 다음과 같다고 할 수 있다.
- Model : Service, DTO, Repository(DAO), Domain(entity)
- View : Front-end
- Controller : Controller
Controller,Repository,Service는 정형화 되어있는 패턴이다
- Controller를 통해서 외부요청을 받고(API),
- Service를 통해서 비즈니스 로직을 만들고(Business Logic),
- Repository에서 데이터를 저장하고(Persistence Logic)
역할을 나누는 것이 이점이다? (개발자가 비즈니스 로직에 집중할 수 있음.)


DTO, Entity, 도메인은 같은 역할을 한다고 보면 되겠다.
Nevertheless, 구분하고자 한다면
entity: 실제 DB의 테이블과 매칭될 클래스DTO: 계층간 데이터 교환을 위한 객체
앞서 살펴본 MVC패턴을 바탕으로 패키지를 구성하고, 프로젝트를 진행한다.
- 정형화 되어있는 패턴인
Controller,Repository(DAO),Service패키지를 만든다.- 각 계층간 데이터 교환을 위한 entity를 만든다. (DTO, Entity)
패키지 구성 방법으로는 레이어드형 아키텍처, 도메인형 아키텍처로 크게 두가지가 있지만 MSA를 적용해 기능별로 나누어 개발하는 방식을 많은 기업이 채택하고 있다는 생각해 레이어드형 아키텍처로 구조를 설계하겠다.

패키지를 구성하였다면, 스프링 컨테이너에 Controller, Repository(DAO), Service를 등록해야한다. (스프링 컨테이너에 스프링 빈을 등록해야 한다.)
스프링 컨테이너에 등록을 해야 컨트롤러가 서비스와 리포지토리를 사용할 수 있다.
참고: 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다(메모리 절약). 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
스프링 빈 등록하는 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- 자바코드로 직접 스프링 빈 등록하기
@Component (@Controller, @Service, @Repository)
@Autowired는 스프링 컨테이너에 등록되어있는 것을 연결해준다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Repository
public class MemoryMemberRepository implements MemberRepository {}

컴포넌트 스캔으로 등록하는 방법이 아닌, 설정 파일을 따로 만들어 등록하는 방법도 있다.
- 서비스와 회원 리포지토리의 @Service, @Repository, @Autowired 애노테이션을 제거하고 진행한다.
- 예시로
SpringConfig.java라는 파일을 만든다.- 해당 파일에 등록하고자하는 패키지를 입력한다.

SpringConfig.java의 코드는 다음과 같다. @Configuration, @Bean 어노테이션을 사용해서 등록한다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
@Controller는 그대로 두고 진행하였다.
해당 방식을 사용하면, Service나 Repository를 바꾸어야할 경우 기존 코드의 변경 없이 config 파일의 코드만 수정하면 된다는 장점이 있다.
(상황에 따라 구현 클래스를 변경해야하면 이 방식이 좋다.)
.. ex) 위 코드에서 Repository를 변경해야하는 경우 MemoryMemberRepository만 바꿔주면 된다.