5장에서는 실제 비즈니스와 직접적으로 연관된 서비스를 구현해보겠습니다.
공부 자료는 인프런 김영한 강사님의 스프링 입문편을 들었습니다.
https://inf.run/Jk5T
서비스
자바 스프링에서 서비스는 앞서 구현한 리포지토리에 접근해 비즈니스와 직접적으로 관련된 동작을 수행하는 코드입니다. 비즈니스 요구사항으로 회원 등록과 조회가 있었습니다. 요구사항을 만족하기 위해 먼저 서비스 패키지를 만든 후, 패키지 안에 MemberService 코드를 구현합니다.
MemberService 전체코드입니다. 메소드를 확인하기 전에 먼저 MemberService 선언에 대해서 알아보겠습니다. 하나의 MemberService 마다 새로운 MemberRepository 를 new 키워드를 통해 생성한다면, 각각의 서비스마다 같은 리포지토리를 사용하는 것이 아닌 각각의 리포지토리를 생성해 사용하게 됩니다. 이렇게되면 메모리 낭비도 심해질 뿐더러, 데이터 통일성이 없어지기 때문에 각각의 서비스에 리포지토리를 통일시켜 주어야 합니다. 코드에서 볼 수 있듯이, 새롭게 선언하는 것이 아닌 MemberService 를 새롭게 만들 때 기존의 MemberRepository 를 매개변수로 넣어주어, 해당 리포지토리를 사용하게 선언하였습니다.
package com.example.demo.service;
import com.example.demo.domain.Member;
import com.example.demo.repository.MemberRepository;
import com.example.demo.repository.MemoryMemberRepository;
import java.util.List;
import java.util.Optional;
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
/**
* 회원가입
*/
public Long join(Member member) {
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
/**
* 회원 조회
*/
public List<Member> findMembers() {
return memberRepository.findAll();
}
public Optional<Member> findOne(Long Id) {
return memberRepository.findById(Id);
}
}
Join 메소드
public Long join(Member member) {
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
- 단순히 입력받은 정보를 앞서 구현한 리포지토리를 통해 저장하는 동작을 할 수 있지만, 완성된 서비스를 위해 아이디가 이미 존재하는지 확인하는 절차( 메소드 )를 거칩니다.
- 절차에 통과한다면, 멤버를 저장하는 리포지토리를 통해 회원을 등록합니다.
- 저장한 회원의 고유번호를 반환하며 메소드를 종료합니다.
validateDuplicateMember 메소드
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("이미 존재하는 회원입니다.");
});
}
- 등록하려는 멤버의 아이디를 검사해, 중복된다면 "이미 존재하는 회원입니다." 를 강제 예외처리 시키는 메소드입니다.
- 앞서 구현한 MemoryMemberRepository 의 findByName 메소드를 통해 아이디 값을 넘겨주어, 반환 값이 존재한다면 강제 예외처리를 진행합니다.
- 기존에는 Join 메소드 안에 구현한 코드지만, 독립적인 기능을 하므로 따로 메소드로 내보내는 리펙토링을 진행하였습니다. IntelliJ 에서 제공하는 간편 리펙토링 단축키는 Cmd + opt + M 입니다.
findMembers, findOne 메소드
public List<Member> findMembers() {
return memberRepository.findAll();
}
public Optional<Member> findOne(Long Id) {
return memberRepository.findById(Id);
}
- 등록한 회원을 조회하는 메소드입니다. findMembers 메소드는 등록한 모든 회원의 리스트를 반환하며 , findOne 메소드는 고유번호를 넘겨받아 존재하면 해당 멤버를, 존재하지 않는다면 Null 값을 반환합니다.
- 앞서 리포지토리에서 구현한 내용이기 때문에, Map 자료구조에 저장된 모든 멤버를 반환하는 findAll 메소드를 호출하면 됩니다.
- 역시 Map 자료구조에 저장된 멤버들 중 고유번호와 일치하는 멤버를 반환해주는 findById 메소드를 호출하면 됩니다.
이번 포스팅에서는 앞서 구현한 리포지토리를 통해 실제 비즈니스 로직인 서비스를 구현해보았습니다. 각각의 서비스마다 리포지토리를 생성하지 않고, 통일하였는지 다시 생각해보면 좋을 것 같습니다. 또한 같은 기능을 하지만, 데이터 저장과 연결된 리포지토리와 비즈니스 로직과 연결된 서비스의 관계 또한 유의깊게 보면 좋을 것 같습니다.
구현한 서비스 코드에 대한 테스트에 대한 포스팅은 생략하고, 다음으로는 스프링 빈에 대한 내용을 포스팅 하겠습니다.
'개인 공부 > Spring' 카테고리의 다른 글
[Spring] #7 JPA의 필요성 (0) | 2022.04.15 |
---|---|
[Spring] #6 스프링 빈 등록 (0) | 2022.01.19 |
[Spring] #4 회원 리포지토리 테스트 케이스 작성 (0) | 2022.01.14 |
[Spring] #3 회원 도메인과 리포지토리 구현 (0) | 2022.01.12 |
[Spring] #2 예제로 통한 백엔드 개발 (0) | 2022.01.12 |