Spring AutoConfiguration의 동작 원리
스프링 부트의 목표
스프링의 복잡한 설정을 최소화하고,
개발자가 빠르게 실행 가능한 애플리케이션을 만들 수 있도록 하는 프레임워크이다.
예를 들어, Redis에 연결된 스프링 애플리케이션을 만들고 싶을 때 우리는
spring-boot-starter-data-redis 의존성을 추가해주면 redisTemplate 빈과 연결 설정이 가능하다.
별도의 설정 없이 RedisTemplate 타입의 빈을 주입받아 사용할 수 있다.
이처럼 스프링 부트의 핵심은 자동 설정과 내장 서버(Tomcat ...)라고 볼 수 있다.
Spring Boot의 AutoConfiguration의 마법 같은 기능은 어떻게 동작하는 것일까?
애플리케이션 실행 과정
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
@SpringBootApplication 어노테이션의 구성
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
}
큰 흐름은 @ComponentScan을 통해 개발자가 정의한 Component들이 Bean으로 먼저 등록이 되고,
@EnableAutoConfiguration을 통해 애플리케이션 구성에 필요한 추가 Bean을 읽어서 등록하게 된다.
@EnableAutoConfiguration
위 어노테이션이 스프링 부트의 자동 설정 기능을 활성화하는 역할을 수행한다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
자세히 보면
@Import({AutoConfigurationImportSelector.class})
를 import하고 있는 것을 확인할 수 있다.
@SpringBootApplication
- @EnableAutoConfiguration
- @Import({AutoConfigurationImportSelector.class})
해당 클래스에서는 자동 구성할 후보 빈들을 불러와 제외되거나 중복된 빈들을 제거하는 작업을 거친 후 자동 구성할 빈들을 반환하는 역할을 수행한다.
AutoConfiguraionImportSelector.class
selectImports()
해당 클래스 내부에는 selectImports 라는 메서드가 존재한다.

해당 메서드를 통해 Imprt할 클래스가 무엇인지 알 수 있게 된다.
해당 메서드는 getAutoConfigurationEntry(..)를 호출하여 엔트리를 반환받게 된다.
즉, 자동 설정의 진짜 시작점이라고 볼 수 있다.
getAutoConfigurationEntry()
자동 설정 후보 리스트를 다듬는 핵심 메서드.

후보 클래스 로딩 → getCandidateConfigurations 호출 (spring.factories / imports 읽음).
- 중복 제거.
- 제외할 클래스 확인 (
exclude속성 등). - 조건 필터링 →
@ConditionalOnClass,@ConditionalOnMissingBean같은 조건 체크. - 이벤트 발행 (
fireAutoConfigurationImportEvents) → 확장 포인트 제공. - 결과 묶기 →
AutoConfigurationEntry객체에 후보/제외 정보 담아서 반환.
즉, 후보들 중에서 실제 등록 가능한 자동 설정 클래스만 추리는 단계
getCandidateFigurations()

이는 자동 설정 원천 후보 클래스를 로딩하는 역할을 수행한다.
META -INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
에서 매핑된 클래스 이름들을 모두 읽어온다.

즉, 자동 설정의 풀(pool) 후보를 모아오는 단계.
정리
main()
└─ SpringApplication.run()
└─ refresh()
└─ registerAnnotationConfigProcessors()
└─ ConfigurationClassPostProcessor 등록
└─ invokeBeanFactoryPostProcessors()
└─ ConfigurationClassPostProcessor 실행
└─ @EnableAutoConfiguration 처리
└─ @Import(AutoConfigurationImportSelector)
└─ selectImports()
└─ getAutoConfigurationEntry()
└─ getCandidateConfigurations()
└─ 후보 정리(중복 제거, 제외, 조건 검사)
└─ 최종 클래스 반환
└─ BeanDefinition 등록
스프링 부트의 자동 설정은 @EnableAutoConfiguration 으로 시작해 AutoConfigurationImportSelector 가 후보 설정 클래스를 수집·필터링하고, ConfigurationClassPostProcessor 가 이를 BeanDefinition 으로 등록하는 구조다.
이 과정은 스프링 컨텍스트 초기화 시점에 ConfigurationClassPostProcessor가 자동으로 호출하면서 진행된다.
즉, 의존성만 추가하면 조건(@ConditionalOnClass, @ConditionalOnMissingBean 등)에 맞는 Bean이 자동 등록되어 개발자는 최소한의 설정만으로 실행 가능한 애플리케이션을 만들 수 있다.