스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
인프런 김영한님 강좌인 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 내용을 학습하며 다룬 글입니다.
문제(저작권, 오류 및 잘못된 부분 등)가 있다면 알려주세요!!
PREV)
[1. 컴포넌트 스캔과 자동 의존관계 설정]
[2. 자바 코드로 직접 스프링 빈 등록하기]
스프링 빈
스프링 컨테이너가 관리하는 자바 객체를 빈(Bean)이라 한다.
자바에서 new를 통해 생성되는 객체를 의미하는 것이 아니라 컨테이너에서 생성하고 관리하는 객체를 의미한다.
이러한 스프링 빈을 등록하고 의존 관계를 설정해주어야 한다.
스프링 빈을 등록하는 방법에는 2가지 방법이 있다
- 컴포넌트 스캔과 자동 의존 관계 설정
- 자바 코드로 직접 스프링 빈 등록
DI(Dependency Injection) , 의존 관계를 외부에서 넣어주는 것에는 3가지 방법이 있다.
- 생성자 주입 : 처음 애플리케이션이 조립되는 시점에 설정된 후, 변경되지 않도록 막을 수 있다.
- 필드 주입 : 중간에 변경할 수 없어서 좋은 방법이 아니다.
- setter 주입 : set 함수를 호출하기 위해 public으로 설정하게 되면, 보안상 좋지 않은 방법이다.
[1. 컴포넌트 스캔과 자동 의존관계 설정]
java/hello.hellospring/controller/MemberController.java
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 //스프링이 스프링 컨테이너에 있는 MemberService를 가져다 연결을 시켜줌(Controller랑 Service를 연결시켜줌, dependency injection)
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
- @Autowired : 객체 생성 시점에 스프링 연관된 객체를 스프링 컨테이너에서 찾아 주입한다. 생성자가 1개뿐이라면, 생략 가능하다. 이렇게 객체 의존 관계를 외부에서 넣어주는 것을 DI(Dependency Injection), 의존성 주입이라 한다.
- memberService가 스프링 빈으로 등록되어 있지 않으면 오류가 발생한다.
@Controller , @Service , @Repository를 각 클래스 선언 위에 추가해주어야 한다.
@Service
public class MemberService {...}
@Repository
public class MemoryMemerRepository implements MemberRepository{..}
이것을 컴포넌트 스캔이라고 한다.
@Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
@Controller , @Service , @Repository는 @Componet를 포함하고 있다..!
- @Component 어노테이션이 있으면 스프링 객체로 생성이 되며, 스프링 컨테이너에 스프링 빈으로 등록된다.
- @Autowired는 위 그림에서의 연결을 의미한다.
- 동일한 패키지 내에서만 컴포넌트 스캔이 진행된다.
[참고]
생성자가 여러 차례 호출되어도, 실제로 생성되는 객체는 하나인 것, 하나의 인스턴스만 생성되는 것을 싱글턴 패턴이라 한다. 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 기본으로 싱글턴으로 등록하여 메모리를 절약한다.
[2. 자바 코드로 직접 스프링 빈 등록하기]
MemberService와 MemberRepository의 @Service, @Repository, @Autowired 어노테이션을 제거.
컴포넌트 스캔을 이용하지 않고 직접 등록하는 방법을 이용해보도록 한다.
java/hello.hellospring/SpringConfig.java
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 {
// memberService를 스프링 빈으로 등록
@Bean
public MemberService memberService() {
return new MemberService(memberRepository()); // 스프링 빈에 등록되어 있는 MemberRepository를 MemberService에 넣어줌
}
// memberRepository를 스프링 빈으로 등록
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
[참고]
DI에는 생성자 주입, 필드 주입, setter 주입 3가지 방법 중, 의존 관계가 실행 중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다. 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드에서는 컴포넌트 스캔을 사용한다.
또, 정형화 되지 않거나 상황에 따라 구현 클래스를 변경해야 한다면, 설정을 통해 스프링 빈으로 등록한다.
@Autowired를 통한 DI는 helloController, memeberService 등과 같이 스프링이 관리하는 객체에서만 동작한다. 스프링 빈으로 등록하지 않고 직접 생성해준 객체에서는 동작하지 않는다.
NEXT)
스프링 입문 - 5. 회원 관리 예제 - 웹 MVC 개발