본문 바로가기
강의 실습/스프링 핵심 원리 - 기본편

컴포넌트 스캔과 의존관계 자동 주입 시작하기

by jint 2026. 4. 20.

스프링 빈 등록시, 자바 코드의 @Bean 이나 XML의 <bean> 태그 등을 이용해 설정 정보에 직접 등록할 스프링 빈을 나열했다.
스프링 빈 개수가 늘어날수록 관리가 어렵고 누락 위험도 있으므로, 스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔 기능을 제공한다.
또한 의존관계도 자동으로 주입하는 @Autowired 기능도 제공한다.

코드로 컴포넌트 스캔과 의존관계 자동 주입을 알아본다.

- src/main/java/hello/core/AutoAppConfig.java

package hello.core;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

import static org.springframework.context.annotation.ComponentScan.*;

@Configuration
@ComponentScan(excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig {

}


컴포넌트 스캔을 사용하려면 설정 정보에 @ComponentScan 을 붙인다. AppConfig 와 다르게 @Bean 으로 등록한 클래스가 하나도 없다.

* 참고
컴포넌트 스캔 사용시 @Configuration 이 붙은 설정 정보도 자동으로 등록되기 때문에, AppConfig, TestConfig 등 앞서 만들었던 설정 정보도 함께 등록되고, 실행된다. (@Configuration 소스코드에 @Component 어노테이션 붙어있음)
따라서 excludeFilters 를 이용해 설정 정보는 컴포넌트 스캔 대상에서 제외했다.
보통 설정 정보를 컴포넌트 스캔 대상에서 제외하지 않지만, 기존 예제 코드를 유지하기 위해서 이 방법을 선택했다.

* 인텔리제이 파일 찾기 : Shift 2번

각 클래스가 컴포넌트 스캔 대상이 되도록 @Component 를 붙인다.

1) MemoryMemberRepository @Component 추가
- src/main/java/hello/core/member/MemoryMemberRepository.java

@Component
public class MemoryMemberRepository implements MemberRepository {
    ...
}


2) RateDiscountPolicy @Component 추가
- src/main/java/hello/core/discount/RateDiscountPolicy.java

@Component
public class RateDiscountPolicy implements DiscountPolicy {
    ...
}


3) MemberServiceImpl @Component, @Autowired 추가
- src/main/java/hello/core/member/MemberServiceImpl.java

@Component
public class MemberServiceImpl implements MemberService {
    ...
    @Autowired // getBean(MemberRepository.class)
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    ...
}


AppConfig 에서 @Bean 으로 직접 설정 정보를 작성했고 의존관계도 직접 명시했다.
하지만 이제 설정 정보 자체가 없기 때문에, 의존관계 주입도 해당 클래스에서 해결한다.
@Autowired 는 의존관계를 자동으로 주입해준다.

4) OrderServiceImpl @Component, @Autowired 추가
- src/main/java/hello/core/order/OrderServiceImpl.java

@Component
public class OrderServiceImpl implements OrderService {
    ...
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
    ...
}


생성자에서 여러 의존관계도 한 번에 주입 가능.

- src/test/java/hello/core/scan/AutoAppConfigTest.java

package hello.core.scan;

import hello.core.AutoAppConfig;
import hello.core.member.MemberService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static org.assertj.core.api.Assertions.*;

public class AutoAppConfigTest {

    @Test
    void basicScan() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);

        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);
    }

}


- 콘솔

21:21:28.093 [Test worker] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner --Identified candidate component class: file [C:\Users\admin\IdeaProjects\core\build\classes\java\main\hello\core\discount\RateDiscountPolicy.class]
21:21:28.094 [Test worker] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner --Identified candidate component class: file [C:\Users\admin\IdeaProjects\core\build\classes\java\main\hello\core\member\MemberServiceImpl.class]
21:21:28.094 [Test worker] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner --Identified candidate component class: file [C:\Users\admin\IdeaProjects\core\build\classes\java\main\hello\core\member\MemoryMemberRepository.class]
21:21:28.095 [Test worker] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner --Identified candidate component class: file [C:\Users\admin\IdeaProjects\core\build\classes\java\main\hello\core\order\OrderServiceImpl.class]
...
21:21:28.130 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Creating shared instance of singleton bean 'autoAppConfig'
21:21:28.133 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Creating shared instance of singleton bean 'rateDiscountPolicy'
21:21:28.134 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Creating shared instance of singleton bean 'memberServiceImpl'
21:21:28.144 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Creating shared instance of singleton bean 'memoryMemberRepository'
21:21:28.145 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Autowiring by type from bean name 'memberServiceImpl' via constructor to bean named 'memoryMemberRepository'
21:21:28.146 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Creating shared instance of singleton bean 'orderServiceImpl'
21:21:28.148 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Autowiring by type from bean name 'orderServiceImpl' via constructor to bean named 'memoryMemberRepository'
21:21:28.148 [Test worker] DEBUG o.s.b.f.s.DefaultListableBeanFactory --Autowiring by type from bean name 'orderServiceImpl' via constructor to bean named 'rateDiscountPolicy'


AnnotationConfigApplicationContext 를 사용하여 설정 정보로 AutoAppConfig 클래스를 넘겨준다.
컴포넌트 스캔이 잘 동작한다.


1. @ComponentScan

컴포넌트 스캔과 자동 의존관계 주입 동작


설정 정보가 없어도 자동으로 스프링 빈을 등록.
@Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록.
기본 이름은 클래스명의 맨 앞글자만 소문자로 하여 등록.
· 빈 이름 기본 전략 : MemberServiceImpl 클래스 -> memberServiceImpl
· 빈 이름 직접 지정 : 스프링 빈 이름 직접 지정시, @Component("memberService") 형식으로 이름 부여


2. @Autowired

@Autowired 의존관계 자동 주입


의존관계 자동 주입
생성자에 @Autowired 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다. 이 때, 기본 조회 전략은 타입이 같은 빈을 찾아서 주입한다.
· getBean(MemberRepository.class) 코드와 동일

 

생성자에 여러개의 파라미터


생성자에 파라미터가 많아도 다 찾아서 자동으로 주입한다.


참고링크 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8?cid=325969

 

스프링 핵심 원리 - 기본편| 김영한 - 인프런 강의

현재 평점 5.0점 수강생 49,555명인 강의를 만나보세요. 스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 스프링 기본 기능, 스프

www.inflearn.com

댓글