Backend/SpringBoot

[기본구조4] 서비스

Dean83 2024. 10. 23. 16:25

Repository Interface 를 컨트롤러 클래스에서 직접 제어 하는것은 보안측면에서 좋지 않다. 또한 코드 중복을 막기 위해서도 서비스 클래스를 이용하여 DB 처리 하는것이 좋다. 서비스 클래스를 따로 두면 엔티티를 DTO 적용하여 데이터 처리를 분리 할 수 있다.

서비스는 비즈니스 로직을 담당한다. 

 

  •  컨트롤러 클래스 -> 서비스 클래스 함수 호출 -> 서비스 클래스에서 Repository Interface 조작
  • @Service 어노테이션을 사용한다. 
  • Service 에는 @Transactional 메소드 어노테이션을 통해 DB 트랜잭션 작업을 하는 메소드를 작성 할 수 있다.
    • @Transactional 어노테이션이 붙은 경우, 스프링 컨테이너는 Controller 에서 Service를 이용할때, 바로 주입하지 않고, Proxy 개체를 생성하여 활용한다. 
    • 따라서, Controller -> Proxy -> Service -> Repository 로 동작을 하게 되는 것이다. 

서비스 예제

@Service
@RequiredArgsConstructor
public class MemberService {
    private final MemberRepository memberRepository;

	@Transactional
    public Page<MemberDTO> searchMembersByName(String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by("name").ascending());
        Member member = memberRepository.findByNameContainingCustom(keyword, pageable);
        MemberDTO dto = MemberDTO.fromEntity(member);
        return dto;
    }
}

 

컨트롤러 에서는 Repository 대신 서비스 클래스를 그대로 Injection 하여 사용하면 된다. 

 

단, 리턴을 할때 엔티티를 직접 리턴하는것 보다 DTO로 변환하여 리턴하는것을 추천한다. 그 이유는 Lazy loading과 Transaction 연관이 있다.  (여기 하단부에 해당 이유가 적혀 있다. https://dean83.tistory.com/343)