본문으로 바로가기

목차

    0. 환경

    1. 변경 전 서비스, 리포지토리 소스코드

    [MemberService]

    @Service
    public class MemberService {
    
        private final MemberRepository memberRepository;
    
        @Autowired
        public MemberService(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
        }
        //( ... ) 생략   
    }

    [MemoryMemberRepository]

    @Repository
    public class MemoryMemberRepository implements MemberRepository {
    
        //메모리에 저장을 하기 위해 Map선언
        private static Map<Long, Member> store = new HashMap<>();
        private static long sequence = 0L;
        //( ... ) 생략   
    }

    2. 컴포넌트 스캔,  자동 의존 관계 설정 어노테이션 지우기

    자바 코드로 직접 스프링 빈 등록을 위해 지워 줍니다. (@Service, @Repository, @Autowired 지워줍니다.)

     

    [MemberService]

    public class MemberService {
    
        private final MemberRepository memberRepository;
    
        public MemberService(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
        }
        //( ... ) 생략   
    }

    [MemoryMemberRepository]

    public class MemoryMemberRepository implements MemberRepository {
    
        //메모리에 저장을 하기 위해 Map선언
        private static Map<Long, Member> store = new HashMap<>();
        private static long sequence = 0L;
        //( ... ) 생략   
    }

    3. 자바 코드로 직접 스프링 빈 등록

    새 클래스를 만들고 @Configuration, @Bean를 사용해 직접 자바 코드로 스프링 빈을 등록해줍니다.

    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());//의존성 주입
        }
    
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository();//구현체
        }
    }

    4. 장점

    컨트롤러, 서비스, 리포지토리처럼 정형화된 경우엔 @Controller, @Service, @Repository, @Autowired를 이용해 사용하면 편리하지만 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하는 경우 직접 설정 파일을 운영하는 방식으로 스프링 빈으로 등록하는 게 유리합니다.

     

    EX)

    1. 아직 데이터 저장소가 선정되지 않았다는 시나리오가 존재함 그러나 빨리 개발은 시작해야 되므로 메모리 저장소 활용하여 개발
    2. 나중에 저장소가 결정됨으로써 구현 클래스 교체가 필요한 상황 발생
    3. 직접 설정 파일 운영 시 복잡하게 소스 변경 필요 없이 구현체만 바꿔치기를 하면 됩니다.
        @Bean
        public MemberRepository memberRepository() {
            return new MemoryMemberRepository();//구현체 부분
        }

    5. xml등록 방식(컴포넌트 스캔)

    • xml로 등록하는 방식도 존재합니다.
    • 과거에 사용하던 방식으로 Legecy Project에선 아직도 사용하고 있기도 하지만 Spring Boot에선 잘 사용하지 않습니다.
    • root-context.xmlservlet-context.xml 에 등록합니다.
    <context:component-scan base-package="com.test.controller" />
    <context:component-scan base-package="com.test.service" />