[스프링 입문]-2

EarlyBird·2021년 10월 26일
0

스프링 입문

목록 보기
2/5
post-thumbnail

김영한님의 스프링 입문 강의 학습 내용입니다.

백엔드 개발

Domain, Repository 생성

domain(Class)

public class Member {

    private Long id;
    private String name;

	//Getter and Setter
}

repository(Interface)

public interface MemberRepository {
    Member save(Member member);
    Optional<Member> findById(Long id);
    Optional<Member> findByName(String name);
    List<Member> findAll();
}

repository(Class)

@Repository
public class MemoryMemberRepository implements MemberRepository{

    //...

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }

    @Override
    public Optional<Member> findByName(String name) {
        return store.values().stream()
                .filter(member -> member.getName().equals(name))
                .findAny();
    }

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    }

    public void clearStore(){
        store.clear();
    }
}
  • Optional : null값을 감싼다.
  • findAny() : filter()로 찾은 결과 중 아무 값이나 하나를 선택
  • id는 중복이 없으나 name은 중복이 발생할 수 있기에 구현 방식이 다르다.

Repository Test Case

public class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach 
    public void afterEach(){
        repository.clearStore();
    }

    @Test 
    public void save(){
        Member member = new Member();
        member.setName("spring");

        repository.save(member);

        Member result = repository.findById(member.getId()).get();
        Assertions.assertThat(member).isEqualTo(result);  //org.assertj.core.api
    }

    @Test
    public void findByName(){
    
    //member1, 2생성

        Member result = repository.findByName("spring1").get();

        Assertions.assertThat(result).isEqualTo(member1);
    }

    @Test
    public void findAll(){
    
    //member1, 2생성

        List<Member> result = repository.findAll();

        Assertions.assertThat(result.size()).isEqualTo(2);
    }
}
  • @AfterEach : 각 테스트 종료된 후 동작
  • @BeforeEach : 각 테스트 실행 전 동작
  • Test는 순서와 관계없이 설계가 되어야한다. -> clear의 이유
  • TDD : Test를 먼저 작성
  • Shift + F6 : Rename
  • Ctrl + Alt + V : Extract Variable

서비스 개발

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    //회원 가입
    public Long join(Member member){
        //이름 중복 회원X
        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 memberId){
        return memberRepository.findById(memberId);
    }
}

서비스 테스트

class MemberServiceTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void afterEach(){
        memberRepository.clearStore();
    }

    @Test
    void join() {
        //given
        Member member = new Member();
        member.setName("hihi");
        //when
        Long saveId = memberService.join(member);
        //then
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());
    }

    @Test
    public void exception(){

    //동일 이름 member1, 2생성

        memberService.join(member1);
        IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
        Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원");

//        try{
//            memberService.join(member2);
//            fail();
//        } catch (IllegalStateException e){
//            Assertions.assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원");
//        }

    }
}

컴포넌트 스캔과 자동 의존관계 설정

  • @Controller : 외부 요청을 받는다.
  • @Service : 비즈니스 로직을 만든다.
  • @Repository : 데이터를 저장한다.
  • @Autowired : 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아 넣어줌(DI), 연결의 의미
  • @Component : 스프링 빈으로 자동 등록(@Controller, @Service, @Repository)

직접 스프링 빈 등록하기

@Service-@Autowired, @Repository 제거 상태

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}
profile
안되면 되게 합시다

0개의 댓글

관련 채용 정보