본문 바로가기
백엔드/스프링

스프링 빈과 의존관계

by dustnn 2025. 5. 18.

인프런 강의 공부 내용이다.

스프링 빈 등록하는 방법

 

다음과 같은 의존관계를 가능케 하는 방법이라고 보면 된다.

스프링 빈으로 등록해서 쓰면 많은 이점이 있기 때문에 보통 등록해서 사용한다.

 

cf) 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본으로 싱글톤으로 등록한다.

쉽게 말해 helloController, memberService, memberRepository 각각 하나씩 등록한다는 뜻이다.

memberService가 아니라 orderService가 memberRepository를 내놓으라고 하면 같은 객체를 내어놓는다는 것이다.

이렇게 메모리 절약 가능. 메모리 도출할 때 좋음

컨테이너에 빈을 등록하고 빈들은 그 안에서 서로 의존관계를 가진다.

 

1. 컴포넌트 스캔을 통한 자동 의존관계 설정: @service, @controller, @repository 붙여서 함

-> 스프링이 자동으로 스프링 컨테이너에 스프링 빈으로 등록

@Service 안에 들어가면 @Component 등록돼있음

=> @Component 애노테이션이 있으면 스프링 빈으로 자동 등록됨

 

2. Java 코드로 직접 스프링 빈 등록하기

 

 

 

1. 컴포넌트 스캔을 통한 자동 의존관계 설정

 

회원을 repository에 저장하고 꺼내오고 하려면 member controller을 만들어야 함

member controller은 MemberService를 통해 회원가입하고 조회할 수 있어야 함(member controller은 memberservice에 의존)

 

MemberController 클래스 만들기

 

@Controller

Spring 창에서 Container라는 통이 보일 거다.

spring container는 MemberController 객체를 생성해 spring에 넣어둬 관리함

 

다음과 같이 new 객체를 생성하면 다른 클래스에서도 사용할 수 있기 때문에 ...

private final MemberService memberService = new MemberService;

 

다음과 같이 생성자로 연결해준다.

 

@Autowired:스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어줌 (의존관계를 외부에서 넣어주는 Dependency Injection)

ex. memberService라는 객체와 spring container에 있는 MemberService를 연결해줌

@Autowired
public MemberController(MemberService memberService){
	this.memberService = memberService;
}

 

helloController는 spring에 등록돼있다. 

MemberService는 @가 없는 그냥 순수한 java 클래스이므로 자신의 역할을 알지 못한다.

 

@Service를 넣어줌

@Service: 스프링에 서비스 관련된 것이 올라오면 MemberServic와 연결해줌.

 

마찬가지로 MemoryMemberRepository에는 @Repository를 써준다.

 

이렇게 정형화된 패턴인 controller, repository, service는 @controller, @repository, @service라는 어노테이션을 붙여주어

관련된 기능이 필요해보일 때 자동으로 연결되도록 해주어야 한다.

 

다음과 같이 memberService는 memberRepository를 필요로 하기 때문에

 

스프링이 MemberService를 생성하여 스프링 컨테이너에 등록하면서 

생성자인 @Autowired 부분을 호출 -> 매개변수인 MemberRepository도 불러와 주입해주는데

현재는 MemoryMemberRepository가 구현체로 있기 때문에  이를 주입해준다.

 

 

2. Java 코드로 직접 스프링 빈 등록하기

 

하나하나 직접 스프링에 등록하는 방법

 

@Bean: 스프링 빈에 등록하라는 어노테이션

 

빈에 등록하기 위해 따로 클래스를 만들어준다 -> "SpringConfig"

-> @Bean을 사용해 코드 작성

 

memberService와 memberRepository를 스프링 빈에 등록

-> 스프링 빈에 등록돼있는 memberRepository를 MemberService에 넣어줌

 

그럼 다음 관계가 완성된다.

 

@Controller은 어쩔 수 없이 써줘야 한다..

 

<생성자 주입>

이런 식으로 생성자로 주입해주는 방법

 

 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();
         // 다른 종류의 구현체로 바꾸고 싶다면 여기만 바꿔주면 됨
         //return new DBMemberRepository();
     }
}

 

 

 

<기억해둘 것>

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

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

(주의) @Autowired 를 통한 DI는 helloController, MemberService 등과 같이 스프링이 관리하는 객체에서만 동작

스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않음..