스프링 빈과 의존관계Spring2023. 1. 29. 18:54
Table of Contents
스프링 빈과 의존관계
스프링 빈이란?
스프링 컨테이너가 관리하는 자바 객체를 말함
스프링 빈을 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정
- 컴포넌트 스캔 : @Component 어노테이션이 있으면 자동으로 등록된다
- @Service , @Repository , @Controller
- 웬만하면 싱글톤으로 설정
- 컴포넌트 스캔 : @Component 어노테이션이 있으면 자동으로 등록된다
- 자바 코드로 직접 스프링 빈 등록하기
의존관계 설정
의존관계 생성 → 멤버 컨트롤러가 멤버 서비스에 의존한다.
1️⃣ 컴포넌트 스캔과 자동 의존관계로 의존관계 설정하기
멤버 컨트롤러에 의존관계를 추가
@Controller
public class MemberController {
// 1번
// private final MemberService memberService = new MemberService();
//2번
private final MemberService memberService;
@Autowired
public MemberController (MemberService memberService){
this.memberService = memberService;
}
}
@Controller 어노테이션을 추가해서 스프링 빈으로 등록
memberService 생성 방법
- 1번째 방법
- 다른 컨트롤러에서도 필요해서 1번 방법으로 생성하면, 여러개 인스턴스를 생성하게되어 공용으로 사용할 수 없음
- 2번째 방법
- 스프링 컨테이너에 등록해서 하나만 사용
- @Autowired 가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다. 즉 스프링 컨테이너에 존재하는 memberService를 찾아서 연결시켜줌
- 이렇게 객체 의존관계를 외부에서 넣어주는 것을 DI (Dependency Injection), 의존성 주입이라 한다.
- 그러기 위해서는 memberService 클래스가 Service 역할이라는 것을 명시해줘야 함
- @Service
@Service public class MemberService { private final MemberRepository memberRepository ; //constructer @Autowired 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 memberId){ return memberRepository.findById(memberId); } }
스프링 컨테이너 의존관계
스프링 컨테이너 { memberController → memberService → memberRepository }
- 위의 의존관계를 완성하기 위해 마무리로 memberRepository도 스프링 빈으로 등록
@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);
store.put(member.getId(),member);
return member;
}
@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))) //memeber에서 같은 네임인 멤버를 찾음
.findAny(); //하나라도 찾으면 바로 반 , 없으면 optional(null)반환
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
public void clearStore(){
store.clear();
}
}
스프링의 정형화된 패턴 ⭐
Controller 를 통해서 외부 요청을 받고
Service를 통해서 내부 비즈니스 로직을 만들고
Repository에서 데이터를 저장
2️⃣ 자바 코드로 직접 스프링 빈 등록하기
- @Controller는 그대로 두고 Service와 Repository에서 @Component와 @Autowired 을 제거
- @Configuration 어노테이션을 이용해 SpringConfig class 생성
- @Bean 어노테이션으로 스프링 빈 등록
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean //스프링 빈 등록
public MemberService memberService(){
return new MemberService(memberRepoistory());
}
@Bean //스프링 빈 등록
public MemberRepository memberRepoistory(){
return new MemoryMemberRepository();
}
}
🗨️ DI
- DI에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다. 의존관계가 실행중에
- 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. 그리고 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
*인프런 스프링 입문 강의를 듣고 스스로 정리한 내용입니다. 블로그에 있는 내용의 출처는 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의입니다. (https://www.inflearn.com/course/스프링-입문-스프링부트)
'Spring' 카테고리의 다른 글
회원관리 (0) | 2023.01.30 |
---|---|
회원관리 예제 (0) | 2023.01.19 |
스프링 웹 개발 기초 (0) | 2023.01.18 |
View 환경설정 (0) | 2023.01.18 |
라이브러리 살펴보기 (0) | 2023.01.17 |
@gani+ :: Gani_Dev :)
꾸준히 기록할 수 있는 사람이 되자 !