꼬물꼬물

스프링 빈과 의존관계 본문

스터디/스프링 입문

스프링 빈과 의존관계

멩주 2022. 8. 28. 14:30

 

MemberController가 MemberService를 통해 실행하기 때문에 Controller는 Service를 의존한다.

스프링 컨테이너가 실행될 때, @Controller를 확인해 해당 컨트롤러를 넣어둔다.  <- 스프링 관리

- 스프링 컨테이너에서 스프링 빈이 관리된다.

controller가 뜰 때 해당 생성자를 호출한다. @Autowired는 스프링 컨테이너에 있는 MemberService와 연결시켜준다.

- 어노테이션(@Controller, @Service, @Repository)으로 스프링 컨테이너에게 알려줘야 한다.

 

controller/MemberController.class

@Controller
public class MemberController {

    // 공용으로 쓰기 위해 스프링 컨테이너에 등록하기
    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) { // Spring Bean에 등록된 MemberService와 연결
        this.memberService = memberService;				// 이게바로 Dependency Injection
    }
}

service/MemberService.class

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository) {
        // 내가 직접 new 하지 않는다.
//        Dependency Injection
        this.memberRepository = memberRepository;
    }
}

repository/MemoryMemberRepository.class

@Repository
public class MemoryMemberRepository implements MemberRepository{

}

test/MemberServiceTest.class

class MemberServiceTest {

//    MemberService memberService = new MemberService();
    // MemberService의 repo와 다를 수 있다.
//    MemoryMemberRepository memberRepository = new MemoryMemberRepository();
    MemberService memberService;
    MemoryMemberRepository memberRepository;

    // 테스트 실행 전 수행
    @BeforeEach
    public void beforeEach() {
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }
}

 

 

스프링 컨테이너에 스프링 빈 등록하는 방법

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

@Component를 포함하는 어노테이션도 스프링 빈으로 자동 등록된다.

 - @Controller

 - @Service

 - @Repository

 

*main이 들어있는 패키지 하위만 스프링 검색이 가능하다!*

 

참고: 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록.(하나로 공유, 메모리 절약)


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

SpringConfig.class

// 하단의 Spring Bean 등록
@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

 

- DI에는 필드 주입, setter 주입, 생성자 주입 3가지 방법이 있다. 의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을권장한다. 

- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용. 

- 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.

- 추후 메모리 리포지토리를 다른 리포지토리로 변경할 예정이므로, 컴포넌트 스캔 방식 대신 자바 코드로 스프링 빈을 설정.

- @Autowired를 통한 DI는 스프링이 관리하는 객체(@Controller, @Service)에서만 동작한다. 스프링 빈으로 등록하지 않고 직접 생성한 객체에서는 동작하지 않는다.

@Controller
public class MemberController {

    // 1. 생성자 주입
    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
    
    // 2. 필드 주입
    @Autowired private MemberService memberService;

    // 3. setter 주입
    private MemberService memberService;

    @Autowired // public하게 노출되어 변경가능성의 위험이 있다. 보통 한 번 세팅하면 바꿀 일이 없다.
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
}

 

의존 관계 주입

1. 생성자

2. 필드

3. 수정자(setter/getter)

4. 일반 메서드

 

단위테스트/통합테스트

'스터디 > 스프링 입문' 카테고리의 다른 글

스프링 DB 접근 기술  (0) 2022.08.29
회원 관리 예제 - 웹 MVC 개발  (0) 2022.08.29
회원 관리 예제  (0) 2022.08.28
스프링 웹 개발 기초  (0) 2022.08.27
프로젝트 환경설정  (0) 2022.08.26