[Spring] 스프링 빈과 의존관계

    코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술(by 김영한) 강의를 바탕으로 정리한 내용입니다.

     

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

     

     

    컴포넌트 스캔 원리

    • @Component 애노테이션이 있으면 스프링 빈으로 자동 등록된다.
    • @Controller 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
    • @Component 를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.
    • @Controller  @Service  @Repository

     

    스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다(유일하게 하나만 등록해서 공유한다) 따라서 같은 스프링 빈이면 모두 같은 인스턴스다. 설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.

     

    MemberController

    @Controller
    public class MemberController {
        //private final MemberService memberService = new MemberService(); 
        // -> new를 하면 다른 컨트롤러에서도 MemberService를 가져다 쓸 수 있음
    
        private final MemberService memberService; //스프링 컨테이너에 등록하고 쓰자!
    
        @Autowired //스프링 컨테이너에서 memberService를 가져옴
        public MemberController(MemberService memberService) {
            this.memberService = memberService;
        }
    }

     

    MemberService

        @Autowired
        public MemberService(MemberRepository memberRepository) { //직접 new를 하지 않아도 memberRepository에서 넣어줌
            this.memberRepository = memberRepository;
        }

     

    MemberRepository

    @Repository
    public class MemoryMemberRepository implements MemberRepository {
        private static Map<Long, Member> store = new HashMap<>();
        private static long sequence = 0L;
        
        /* ... */
    }

     

     

    2. 자바 코드로 직접 스프링 빈 등록하기

     

    @Configuration
    public class SpringConfig {
       /*
       * memberService와 memberRepository를 스프링 빈에 등록
       * -> 스프링 빈에 등록되어있는 memberRepository를 memberService에 넣어줌
       */
        
        @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
    
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository()
        }
    }

     

    현재 상황 

    - DB가 정해지지 않았기 때문에 메모리로 만들고 나중에 교체하자 !

    → 인터페이스 설계 + 구현체로 MemoryMemberRepository 사용

    → 나중에 실제 DB에 연결하는 리포지토리로 바꿔버릴 것임 (but 기존 코드의 수정 없이!!!)

     

    ex ) 

    @Configuration
    public class SpringConfig {
       /*
       * memberService와 memberRepository를 스프링 빈에 등록
       * -> 스프링 빈에 등록되어있는 memberRepository를 memberService에 넣어줌
       */
        
        @Bean
        public MemberService memberService() {
            return new MemberService(memberRepository());
        }
    
        @Bean
        public MemberRepository memberRepository() {
            return new DBMemberRepository() //여기만 수정
        }
    }

     

     

     

    댓글