Programming/Spring Boot

Spring Boot 자동 구성 AutoConfiguration 동작 원리 파헤치기

Jan92 2023. 7. 21. 00:38
반응형

Spring Boot 자동 구성 AutoConfiguration 동작하는 원리 파헤치기

 

spring-boot-autoconfigure

Spring Boot AutoConfiguration

자동 환경 설정(AutoConfiguration)은 Spring Boot의 가장 대표적인 기능이라고 할 수 있는데요.

스프링 부트는 spring-boot-project의 하위 모듈인 'spring-boot-autoconfigure'라는 프로젝트를 통해 web, aop, jdbc, jpa, redis 등, 수많은 자동 환경 설정(자동 구성)을 제공합니다.

(spring-boot-starter 안에 spring-boot-autoconfigure가 포함되어 있습니다.)

 

개발자의 입장에서는 사용할 라이브러리의 의존성만 추가하게 되면 autoconfigure를 통해서 해당 라이브러리에 대한 구성(필요한 빈 설정과 생성)이 자동으로 이루어지기 때문에 Spring에서 처럼 수동으로 빈 등록 및 설정을 하지 않아도 된다는 장점이 있습니다.

 

아래 내용은 스프링 부트의 자동 구성인 AutoConfiguration이 동작하는 원리가 궁금하여 직접 코드를 따라가 보며 정리한 내용입니다.

(해당 포스팅은 org.springframework.boot 3.1.1 버전을 기준으로 작성된 내용입니다.)

 

 


@SpringBootApplication

@SpringBootApplication

실제 코드상에서의 자동 구성(auto configuration)@SpringBootApplication 어노테이션에서 부터 시작되는데요.

 

큰 흐름은 @ComponentScan 어노테이션을 통해 개발자가 정의한 Component들이 Bean으로 먼저 등록되고, @EnableAutoConfiguration 어노테이션으로 인해 AutoConfiguration이 동작하여 애플리케이션 구성에 필요한 추가 Bean들을 읽어서 등록하게 됩니다.

 

***

자동 구성 동작 과정에서 개발자가 정의하여 먼저 등록된 Component들을 판단하여 필터링하는 작업이 포함되어 있기 때문에 Bean이 중복 생성되는 상황은 발생하지 않습니다.

 

 

@EnableAutoConfiguration

@EnableAutoConfiguration

@EnableAutoConfiguration 어노테이션에 대해 조금 더 자세하게 살펴보면, 해당 어노테이션 내부에서 AutoConfigurationImportSelector 클래스를 import 하는 것을 볼 수 있는데요.

 

AutoConfigurationImportSelector 클래스에서는 자동 구성할 후보 빈들을 불러와 제외되거나 중복된 빈들을 제거하는 작업을 거친 후 자동 구성할 빈들을 반환하는데, 자세한 동작은 이어지는 내용을 통해 살펴보겠습니다.

 

 


AutoConfigurationImportSelector

AutoConfigurationImportSelector class

자동 구성이 동작하는 원리를 살펴보기 위해 AutoConfigurationImportSelector 클래스의 getAutoConfigurationEntry() 메서드를 디버깅해 보았는데요.

 

 

ImportCandidates load() method

getCandidateConfigurations() 메서드를 타고 들어가 보면 ImportCandidates 클래스의 static method인 load() 메서드를 통해 META-INF/spring/org.springframework.autoconfigure.AutoConfiguration.imports 파일에 있는 146개의 AutoConfiguration 클래스들의 경로가 포함된 풀 네임을 가져오는 것을 확인할 수 있습니다.

 

 

importCandidates

이처럼 getCandidateConfigurations() 메서드를 통해 자동 구성에 사용될 모든 후보 빈들의 정보를 가져오는데요.

 

 

getAutoConfigurationEntry() method

다시 getAutoConfigurationEntry() 메서드로 돌아가면, getAttributes() 메서드에서는 exclude, excludeName이라는 key를 가진 AnnotationAttributes 인스턴스를 반환하는데, 아래 getExclusions() 부분과 checkExcludedClasses(), removeAll(exclusions) 메서드들을 통해 spring boot 자동 구성을 제외하는 bean들을 파악하여 제거하게 됩니다.

(AnnotationAttributes는 LinkedHashMap<String, Object>를 상속받은 클래스입니다.)

 

 


getConfigurationClassFilter().filter(configurations)

spring.factories

getAutoConfigurationEntry() 메서드의 내부 과정을 조금 더 자세하게 살펴보면, getConfigurationClassFilter() 메서드에서는 spring-boot-autoconfigure 라이브러리 내부의 META-INF/spring/spring.factories 파일을 읽어 OnBeanCondition, OnClassCondition, OnWebApplicationCondition 필터를 담은 ConfigurationClassFilter를 반환하는 것을 확인할 수 있었습니다.

 

여기서 OnBeanCondition, OnClassCondition, OnWebApplicationCondition 3개의 필터는 이어지는 filter(configurations) 메서드에서 각각의 AutoConfiguration이 가진 @Conditional을 통해 조건을 만족하는지 여부를 확인하는데요.

조건이 맞지 않는 경우 해당 AutoConfiguration이 동작하지 않도록 제외시키는 역할을 수행합니다.

 

 

org.springframework.boot.autoconfigure.condition.OnBeanCondition

확인 대상 : @ConditionalOnBean, @ConditionalOnMissingBean, @ConditionalOnSingleCandidate

 

org.springframework.boot.autoconfigure.condition.OnClassCondition

확인 대상 : @ConditionalOnClass, @ConditionalOnMissingClass

 

org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

확인 대상 : @ConditionalOnWebApplication, @ConditionalOnNotWebApplication

 

(@Conditional과 @Conditional의 확장된 기능에 대한 자세한 내용은 포스팅 하단 참고자료를 통해 살펴보실 수 있습니다.)

 

 

getConfigurationClassFilter().filter(configurations)

이어서 동작하는 filter() 메서드에서는 앞의 과정을 통해 가져온 configurations(146개의 AutoConfiguration이 포함된)과 3개의 filter(OnBeanCondition, OnClassCondition, OnWebApplicationCondition)의 비교 과정을 거쳐 실제로 bean으로 등록될 25개의 AutoConfiguration을 추리게 됩니다.

 

 

FilteringSpringBootCondition Class match method()

filter() 메서드 내부에서 동작하는 match() 메서드의 코드는 다음과 같은데요.

여기서 비교를 하는구나 정도만 알 수 있었고 세부적인 코드는 이해하기가 어려웠습니다.

 

 


정리

정리를 해보자면, 스프링 부트 자동 구성의 큰 흐름은 아래와 같이 진행됩니다.

 

1. main 메서드가 실행되고 @SpringBootApplication -> @EnableAutoConfiguration 어노테이션으로 인해 자동 구성을 위한 AutoConfigurationImportSelector 클래스의 내부 메서드가 동작하게 됩니다.

 

2. AutoConfigurationImportSelector 클래스 내부의 getAutoConfigurationEntry() 메서드 동작 과정에서 META-INF/spring/org.springframework.autoconfigure.AutoConfiguration.imports 파일에 등록된 AutoConfiguration 클래스 정보를 읽어오고 spring.factories에서는 자동 구성에 사용될 필터 정보를 읽어옵니다.

 

3. spring.factories에서 읽어온 3개의 필터(OnBeanCondition, OnClassCondition, OnWebApplicationCondition)를 통해 AutoConfiguration.imports 파일에 등록된 AutoConfiguration 클래스를 필터링합니다.

 

4. 필터링을 통해 실제 적용될 AutoConfiguration 클래스들만 남게 됩니다.

 

 

 

 

< @Conditional, @ConditionalOnXxx 기능에 대한 포스팅 >

2023.07.18 - [Programming/Spring Boot] - @Conditional 어노테이션의 기능과 확장(@ConditionalOnXxx)

 

 

< 참고 자료 >

http://dveamer.github.io/backend/SpringBootAutoConfiguration.html

https://live-everyday.tistory.com/235

반응형