꼬물꼬물
스프링 빈과 의존관계 본문

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 |