티스토리 뷰
[SPRING]스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 섹션4 (스프링 빈과 의존관계)
chaewonni 2023. 11. 27. 15:07💡컨포넌트 스캔과 자동 의존관계 설정
회원 컨트롤러가 회원서비스와 회원 리포지토리를 사용할 수 있게 의존관계를 준비한다.
MemberController가 MemberService를 통해 회원가입하고, 데이터 조회할 수 있어야 하는데, 이것을 MemberController가 MemberService를 의존하는 '의존관계'에 있다고 한다.
💻MemberController 생성
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
//controller 통해서 외부 요청 받고, 서비스에서 비즈니스 로직 만들고, 리포지토리에 데이터 저장 -> 정형화된 패턴
@Controller
public class MemberController { //얘도 spring 컨테이너가 관리를 하게 됨
//private final MemberService memberService = new MemberService();
//new 해서 하면 memberCotroller말고 다른 controller들디 memberService가져다 쓸 수 있음
//여러개의 인스턴스 생성할 필요 없이 하나 생성해놓고 공용으로 쓰면 됨 -> spring 컨테이너에 하나 등록하고 쓰기 (하나만 등록이됨)
private final MemberService memberService;
@Autowired //그런데 생성자에 AutoWired라고 되어 있으면 이 멤버 서비스를 스프링이
// 스프링 컨테이너에 있는 멤버 서비스를 가져다가 연결을 딱 시켜줍니다
// 생성자에서 이렇게 쓰면 멤버 컨트롤러가 생성이 될 때 스프링 빈에 등록되어 있는 멤버 서비스를 객체를 가져다가 넣어줌 = dependency Injection
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
@Controller를 통해 컨트롤러가 스프링 빈(초록색 콩 모양)에 등록된다.
@Autowired는
생성자에 Autowired라고 되어 있으면 스프링이 스프링 컨테이너에 있는 멤버 서비스를 가져다가 연결을 시켜준다.
생성자에서 이렇게 쓰면 멤버 컨트롤러가 생성이 될 때 스프링 빈에 등록되어 있는 멤버 서비스를 객체를 가져다가 넣어준다. = dependency Injection
but, 위 코드를 바로 실행하면 오류가 난다.
MemberController가 MemberService를 통해 회원가입하고 데이터 조회하기 위해 @Autowired를 통해 스프링 컨테이너에 있는 MemberService를 가져와야 하는데, 현재 스프링 컨테이너에 MemberService가 없다.
💻스프링 컨테이너에 스프링 빈 연결
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
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 = new MemoryMemberRepository();
private final MemberRepository memberRepository;
@Autowired //MemberService 등록하면서 이 생성자도 호출함
//그런데 그때 이 오토 와이어드가 있으면 아 너는 멤버 리포지토리가 필요하구나고 해서
//스프링 컨테이너에는 멤버 리포지토리를 넣어줌
//memoryMemberRepository가 구현체로 있어서 이 memoryMemberRepository를 서비스에 주입해줌
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Service를 통해 MemberService를 스프링 컨테이너에 넣어 스프링 빈에 등록해주었다.
이제 MemberService는 MemberController와 서로 연결되는 의존관계이다.
MemberService가 MemberRepository의 메서드인 save, findById, findByName을 사용해야 하므로, 여기도 @Autowired 해주었다.
이제 @Autowired를 통해 스프링 컨테이너에 있는 MemberRepository를 가져다 연결시켜주면 된다.
그러나 현재 스프링 컨테이너에 MemberRepository가 없으므로 아까처럼 이도 스프링 빈에 등록해줘야 한다.
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import org.springframework.stereotype.Repository;
import java.util.*;
@Repository
public class MemoryMemberRepository implements MemberRepository{
@Repository 코드를 추가하여 MemberRepository의 구현체인 MemoryMemberRepository를 스프링 빈으로 등록시켜주었다.
이제 memberService 와 memberRepository 가 스프링 컨테이너에 스프링 빈으로 등록되었고, 의존관계도 확인할 수 있다.
💻 추가 설명
지금까지 한 건 컴포넌트 스캔과 자동 의존관계 설정 방법이었다.
💡자바 코드로 직접 스프링 빈 등록하기
💻 자바 코드로 스프링 빈 연결
먼저, MemberService와 MemoryMemberRepository의 @Service, @Repository, @Autowired 를 지워줘야 한다.
단, MemberController는 그대로 냅둔다.
package hello.hellospring.service;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
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 = new MemoryMemberRepository();
private final MemberRepository memberRepository;
//@Autowired //MemberService 등록하면서 이 생성자도 호출함
//그런데 그때 이 오토 와이어드가 있으면 아 너는 멤버 리포지토리가 필요하구나고 해서
//스프링 컨테이너에는 멤버 리포지토리를 넣어줌
//memoryMemberRepository가 구현체로 있어서 이 memoryMemberRepository를 서비스에 주입해줌
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
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<>();
//주석 처리 해줌
그리고 이제 SpringConfig라는 새로운 클래스 파일을 생성해야 프로젝트를 실행할 때 오류가 발생하지 않는다.
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
//MemberService는 memberRepository 사용하도록 메서드 호출
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
// return new DbMemberRepository();
}
}
이제 스프링 컨테이너에 스프링 빈으로 등록이 되었고, 서로 의존관계를 가지게 되었다.
💻주의 및 참고
여기서는 향후 메모리 리포지토리를 다른 리포지토리로 변경할 예정이므로, 컴포넌트 스캔 방식 대신에 자바 코드로 스프링 빈을 설정하였다.
@Bean
public MemberRepository memberRepository() {
return new DbMemberRepository();
}
자바 코드로 스프링 빈을 설정하면 나중에 return new DbMemberRepository(); 이렇게만 바꿔주면 된다.
public static void main(String[] args) {
MemberService memberService = new MemberService(); //동작하지 않음
} 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
'Spring' 카테고리의 다른 글
- Total
- Today
- Yesterday
- 스프링부트
- 지연로딩
- 파이썬
- 커뮤니티
- 영속
- SQL
- 스프링
- 다이나믹 프로그래밍
- 백준
- 자바 스프링
- SQL 레벨업
- elasticsearch
- 백준 파이썬
- 로깅
- DP
- 북마크
- 스프링 커뮤니티
- 스프링 북마크
- 인텔리제이
- 웹MVC
- 회원탈퇴
- 프론트엔드
- EnumType.ORDINAL
- 준영속
- 로그아웃
- 비영속
- 웹 MVC
- JPA
- SQLD
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |