mojo's Blog
스프링 빈과 의존관계 본문
컴포넌트 스캔과 자동 의존관계 설정
1. controller 폴더 아래에 MemberController 클래스를 형성한다.
코드는 아래와 같이 작성한다.
package hello.hellospring.controller;
import hello.hellospring.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
}
- @Controller : Controller 임을 알리는 애너테이션이다.
- @Autowired : 스프링 컨테이너에서 MemberService의 객체를 가져오도록 하는 것이다.
2. MemoryService 클래스 상단부에 다음과 같이 애너테이션을 달아준다.
@Service
public class MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
- @Service : 스프링 컨테이너에서 MemberService를 등록해준다. (MemberController 객체를 컨트롤러에게 보내는 역할)
- @Autowired : 스프링 컨테이너에서 MemberRepository의 객체를 가져오도록 한다.
3. MemoryMemberRepository 클래스 상단부에 다음과 같이 애너테이션을 달아준다.
@Repository
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
...
}
- @Repository : 스프링 컨테이너에서 MemoryMemberRepository를 등록해준다. (MemberRepository 객체를 컨트롤러에게 보내는 역할)
4. hello.hellospring 폴더 아래의 HelloSpringApplication 을 실행해본다.
※ 스프링 빈 등록하는 2가지 방법
- 컴포넌트 스캔과 자동 의존관계 설정 (방금 등록한 방법)
- 자바 코드로 직접 스프링 빈 등록하기
※ 컴포넌트 스캔과 자동 의존관계 설정
- @Component : 애너테이션이 있으면 스프링 빈으로 자동 등록된다.
- @Controller : 컨트롤러가 스프링 빈으로 자동 등록된 이유도 컴포넌트 스캔 때문이다.
- @Component 를 포함하는 다음 애너테이션도 스프링 빈으로 자동 등록된다. (@Controller, @Service, @Repository)
만약 아래의 그림과 같이 java 폴더 아래에 hello.hellospring 폴더 말고 다른 폴더를 형성한 후에 해당 폴더에 임의의 클래스를 형성한 후 @Component 를 통해 스프링 빈이 자동으로 등록될까?
HelloSpringApplication 는 hello.hellospring 패키지 안에 있는데 해당 패키지의 하위에 있는 모든 것을 스프링이 자동으로 모두 찾아서 스프링 빈을 등록한다.
따라서 Demo 패키지 안에 있는 것은 스프링 빈이 등록이 되지 않는다. (컴포넌트 스캔을 하지 않음)
참고 : 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다. (유일하게 하나만 등록해서 공유한다)
따라서 스프링 빈이면 모두 같은 인스턴스이다.
설정으로 싱글톤이 아니게 설정할 수 있지만, 특별한 경우를 제외하면 대부분 싱글톤을 사용한다.
자바 코드로 직접 스프링 빈 등록하기
1. hello.hellospring 폴더 아래에 SpringConfig 클래스를 형성한다.
2. MemberController, MemoryMemberRepository, MemberService 의 애너테이션을 지워준다.
@Controller
public class MemberController {
private final MemberService memberService;
public MemberController(MemberService memberService){
this.memberService = memberService;
}
}
- @Controller만 남겨둔다.
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
...
}
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
3. 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());
}
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
}
4. 정상적으로 실행되는지 확인해본다.
DI(Dependency Injection)에는 필드 주입, setter 주입, 생성자 주입 이렇게 3가지 방법이 있다.
의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.
실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다.
그리고 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.
'@Autowired'를 통한 DI는 'helloController', 'MemberService' 등과 같이 스프링이 관리하는 객체에서만 동작한다.
스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
'Spring' 카테고리의 다른 글
순수 JDBC & 스프링 JdbcTemplate (0) | 2022.01.13 |
---|---|
회원 관리 예제 - 웹 MVC 개발 (0) | 2022.01.13 |
회원 관리 - 백엔드 개발 (0) | 2022.01.12 |
스프링 웹 개발 기초 (0) | 2022.01.11 |
IntelliJ로 프로젝트 생성 및 view 환경설정 (0) | 2022.01.10 |