1. 스프링빈과 의존관계
스프링빈을 설정하고 의존관계를 설정하기
- 회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비하자.
- 화면을 붙이고 싶을 때 필요한 두 가지 : 컨트롤러 + 뷰 템플릿 (회원가입과, 회원가입을 위한 Html 파일)
- 멤버서비스를 통해서 회원가입 멤버서비스를 통해서 데이터 조회할 수 있는 것을 의존관계가 있다고 한다.
2. 인텔리제이 IS Never USED 경고가 뜰 땐
📌 이 티스토리를 참고하여 설정을 변경해주면 쉽게 처리 된다.
3. 정형화된 관계 설정(스프링 컨테이너 만들기)
- 스프링 컨테이너에 연결하기 위해서는 그저 자바클래스에 불과한 멤버 서비스에 서비스인 것을 알려주어야 하고 또한 리포지토리 또한 리포지토리인 것을 표시해서 알려야 한다.
- 그리고 사용할 객체를 new 연산자를 통해서 생성하기 보다는 Autowired를 사용해서 스프링이 연결해서 1개로만 사용하고 관리할 수 있게 해야 한다. (이를 의존관계 설정이라고 한다.)
4. 스프링 빈을 등록하는 2가지 방법
- 컴포넌트 스캔 자동 의존관계 설정
- @Service -> 서비스임을 알림
- @Repository -> 레포지토리임을 알림
- @Controller -> 컨트롤러임을 알림
- 위의 항목들은 @Component를 포함하고 있다. 그렇기에 사용하기만 하면 자동으로 Spring bean으로 등록된다.
- Autowired -> 연관 관계 설정
- 자바 코드로 직접 스프링 빈 등록하기
👉 두 가지 모두를 알아야 한다.
<스프링 빈(Bean)이란?>
- Spring IOC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부른다.
- 이때 new 연산자를 통해서 객체를 생성하게 되면 new 연산자를 통해 생성된 객체는 빈이 아니게 된다.
- 다시 말해서 Spring에서의 빈은 ApplicationContext가 알고 있는 객체 즉, ApplicationContext가 만들어서 그 안에 담고 있는 객체를 의미한다.
위의 사진은 간단하게 컴포넌트 스캔 자동 의존관계 설정 하는 방식이다.
5. 무작정 Annotation 사용이 가능할까?
< Annotation이란? >
- Annotation은 @Component @Service @Repository @Controller 등과 같은 것들을 의미한다.
- 또한 이들은 @Component @Service @Repository @Controller이 붙은 클래스 Bean을 찾아 Context에 Bean을 등록해주는 Annotation이다.
- 즉, 스프링 컨테이너에 빈을 등록해주는 기능을 한다.
< 무작정 Annotation 사용이 가능할까? >
- 아무 클래스에 Annotation을 사용해서 Bean 등록을 해주는 것은 원칙적으로 불가능하다.
- 왜냐하면 하위 패키지까지 전부 찾아서 등록하기 때문에 하위 패키지가 아니거나 하위 패키지가 동일하지 않은 경우엔 Bean으로 등록하지 않기 때문이다.(@ComponentScan)
- 등록하고 싶다면 따로 등록은 가능하다.
6. Spring Bean 등록
- 기본으로 싱글톤으로 등록한다. (싱글톤이란? 유일하게 등록해서 공유한다.)
- 멤버 서비스는 멤버서비스 하나만, 멤버 리포지토리는 멤버리포지토리 하나만 이런식으로 등록하는 것을 싱글톤이라 한다.
- 따라서 같은 스프링 빈이면 모두 같은 인스턴스이다.
- 설정으로 싱글톤이 아니게 설정은 가능하지만 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
7. Spring Bean에 컴포넌트 스캔 자동 의존관계 설정한 코드
<컨트롤러 설정과 MemberService와의 연관 관계 설정>
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller //컴포넌트 스캔
public class MemberController {
private final MemberService memberService;
@Autowired //연관관계
public MemberController(MemberService memberService){
this.memberService = memberService;
}
}
<리포지토리 설정>
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;
import java.util.*;
@Repository
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
@Override
public Member save(Member member) {
member.setId(++sequence); //ID 세팅
store.put(member.getId(),member); //스토어에 저장
return member;
}
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id)); //null여도 반환 가능
}
@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();
}
}
<서비스 설정과 멤버 리포지토리가 필요한 멤버 서비스를 연관 관계를 설정>
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired //멤버 서비스는 멤버 리포지토리어가 필요
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
/*직접 new로 생성하는 것이 아닌 외부에서 넣어주게 해야
같은 객체를 가르키고 있도록 할 수 있다. */
}
//회원가입
public long join(Member member){
//같은 이름이 있는 중복 회원 X
validateDuplicateMember(member); //중복회원 검증
memberRepository.save(member);
return member.getId();
}
//refactoring 하는 단축키 ctrl + Alt + m (윈도우 기준)
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m ->{ //null이 아닌 값이 있으면 !! -> Optional이라서 가능
throw new IllegalStateException("이미 존재하는 회원입니다.");
} );
}
//전체 회원 조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId){
return memberRepository.findById(memberId);
}
}
'Back-End > Spring' 카테고리의 다른 글
[SpringBoot][스프링 입문] - 5.1 회원 웹 기능 - 홈 화면 추가 (0) | 2021.12.27 |
---|---|
[SpringBoot][스프링 입문] - 4.2 자바 코드로 직접 스프링 빈 등록하기 (0) | 2021.12.25 |
[SpringBoot][스프링 입문] - 3.4 회원 서비스 개발 / 3.5 회원 서비스 테스트 (0) | 2021.12.23 |
[SpringBoot][스프링 입문] - 3.2 회원 도메인과 리포지토리 만들기 / 3.3 회원 리포지토리 테스트 케이스 작성 (0) | 2021.12.23 |
[SpringBoot][스프링 입문] - 3.1 비니지스 요구사항 정리 (0) | 2021.12.23 |