HJW's IT Blog

Spring Bean 과 의존관계 설정 두가지 방법 본문

SPRING

Spring Bean 과 의존관계 설정 두가지 방법

kiki1875 2024. 11. 25. 15:58

Component Scan과 자동 의존관계 설정

Spring은 기본적으로 @ComponentScan을 통해 특정 패키지와 그 하위 패키지를 스캔하여 @Component가 붙은 클래스를 Bean으로 등록한다.

@SpringBootApplication에 이미 @ComponentScan이 포함되어 있어, 별도의 설정 없이도 이러한 동작이 가능하다.

Spring Bean 등록 예시


@Controller
public class MemberController {
}

위와 같이 선언하면, Spring Container가 생성된 후 MemberController 객체를 생성하여 Spring이 관리하게 된다.

의존성 주입 예시

MemberService를 사용하려면 해당 의존성을 Spring Container에 등록하고, 주입받아야 한다.

@Controller
public class MemberController {
    private final MemberService memberService;

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

위 코드에서 @Autowired 어노테이션을 사용하면, Spring이 memberService에 연결된 객체를 Spring Container에서 찾아 주입한다. 이는 이전 테스트에서 개발자가 직접 의존성을 주입하던 방식과는 대조적이다.

주의 사항

  • MemberService와 MemberRepository도 Spring Container에 등록되어야 한다.
    • 이를 위해 각각 @Service, @Repository 어노테이션을 선언해 주어야 한다.
  • @Component 어노테이션의 역할
    • @Service, @Controller, @Repository는 모두 @Component를 포함하고 있으며, 해당 클래스가 Spring Bean으로 자동 등록되도록 한다.

생성자와 @Autowired

  • 생성자에 @Autowired가 있으면 객체 생성 시점에 Spring Container에서 해당 Spring Bean을 찾아 주입한다.
  • 생성자가 하나일 경우 @Autowired는 생략 가능하다. Spring이 자동으로 의존성을 주입한다.
  • 생성자가 여러 개일 경우, 어떤 생성자를 사용할지 명시적으로 지정하기 위해 @Autowired를 반드시 추가해야 한다.

Spring Bean 등록 시 Singleton

Spring Container에 등록된 Bean은 기본적으로 Singleton으로 관리된다. 이는 애플리케이션 전반에 걸쳐 동일한 인스턴스를 재사용하도록 보장한다.

Java 코드로 직접 스프링 Bean 등록하기

@Configuration
public class SpringConfig {
    
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }
    
    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

위 예시는 Spring 에서 Java Config 를 활용하여 직접 Bean을 등록하는 예시이다.

@Configuration 을 통해 해당 클래스가 설정 파일임을 명시하고, @Bean 을 통해 정의된 객체들을 Spring Bean 으로 등록 / 관리한다.

작동 원리

  1. Spring이 SpringConfig 클래스를 읽고, @Bean 메서드를 호출한다.
  2. memberService() 메서드가 호출되어 MemberService 객체가 생성되고, 이를 Spring Container에 등록한다.
  3. memberRepository() 메서드가 호출되어 MemberRepository 객체가 생성되고, 이를 Spring Container에 등록한다.
  4. memberService() 메서드 내부에서 memberRepository() 메서드를 호출하므로, 생성된 MemoryMemberRepository 객체가 MemberService의 생성자에 주입된다.

Java Config 방식의 장점

  1. 명시적 구성
    • @ComponentScan 을 사용하는 방식에 비해, 의존성이 명시적으로 관리된다. 우리의 예시에서 MemberRepository 는 인터페이스이다. 그렇다면 어떤 MemberRepository 가 들어갈지, (MemoryMemberRepository) 를 코드에서 명시할 수 있는 것이다.
  2. 테스트 용이성
    • Java Config 를 통해 구현체를 쉽게 교체할 수 있다. 즉, MemberRepository 의 다른 구현체로 바꾸고 싶다면, JavaConfig 의 내용만 바꾸어 주면 된다.