Spring Boot

Spring Boot 자동 설정 원리

iksadnorth 2023. 7. 27. 12:39

👣 개요

Spring Boot는 Spring Framework에 비해 비즈니스 코드에만 집중하기 쉬운데 
그 이유 중 하나가 'Auto Configuration 기능'이다.

예를 들어, Spring에서 Tomcat 관련 설정을 하지 않으면 오류가 발생하는데 
Spring Boot는 이미 관련 기본 설정을 미리 하기 때문에 Tomcat 설정을 하지 않고도
Tomcat을 구동시킬 수 있을 뿐더러 원한다면 맘대로 커스터마이징을 할 수 있다.

해당 게시물은 어찌하여 Spring Boot에서는 위와 같이 기본 설정을 해줄 수 있고
어찌 커스터마이징 하는지 작성하고자 한다.

 

👣 Spring Boot의 Bean 수집 방법

Spring Boot에는 서버를 구동시키기 위한 Application.java 파일이 필요하고 해당 클래스의 위치는 다음과 같다.

com
└─ example
   └─ project
      ├─ controller
      ├─ service
      ├─ repository
      ├─ ...
      └─ Application.java (서버 구동 클래스)

그리고 해당 클래스는 다음과 같이 구성되어 있다.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

👣 @SpringBootApplication

@SpringBootApplication는 3개의 주요 Annotation이 내포되어 있다.

@SpringBootApplication
= @SpringBootConfiguration
+ @ComponentScan
+ @EnableAutoConfiguration

@SpringBootConfiguration
 해당 Annotation은 @Configuration 와 내용이 같고 기능은 단지 'Bean Container에 Bean 객체로 등록한다는 것'이다.
유일한 차이점은 한 서비스 내에 1번만 사용할 수 있다는 점이다.

@ComponentScan
해당 Annotation은 해당 Annotation이 붙은 클래스의 '동일 디렉토리 혹은 자손 디렉토리 중'
@Component가 붙은 모든 클래스를 Bean으로 등록하는 것이다.
쉽게 말해서 프로젝트 내에 정의한 모든 Bean 객체를 Bean Container에 등록하는 것을 의미한다.
해당 Annotation이 검색하는 Annotation은 다음과 같다.

  • @Configuration
  • @Repository
  • @Service
  • @Controller
  • @RestController

@EnableAutoConfiguration
Spring Boot의 라이브러리를 살펴보면, org.springframework.boot.autoconfigure라는 패키지에
spring.factories 라는 설정 파일이 존재한다. 다음은 해당 설정 파일의 내용이다.

위 파일에는 org.springframework.boot.autoconfigure.EnableAutoConfiguration 라는 속성에 수많은 클래스들이 포합되어 있다. 해당 설정 클래스들을 토대로 기본적인 설정들을 제공하는 것이다.

본론으로 돌아와 @EnableAutoConfiguration의 역할에 대해 말하면
'위 spring.factories에 근거해 기본 설정 파일을 Bean 객체로 등록하는 역할을 수행한다'라는 것이다.

좀더 깊게 살펴보면 각 설정 파일은 대략 아래와 같은 구조로 구성되어 있다.

@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
    ...
}

기본적으로 @Configuration이라는 어노테이션을 가지고 있고 
그 다음은 때에 따라 @ConditionalOnXXX 와 같은 어노테이션을 가지고 있다.
해당 어노테이션은 조건부적으로 Bean 객체를 등록하거나 등록하지 않는 등의 기능을 가지고 있습니다.
예를 들어, 서버의 Type이 Servlet 일 때만 등록된다든지 이미 관련 설정이 되어 있다든지 등등을 예시로 들 수 있습니다.

이런 설정을 알아야 하는 이유는
해당 프레임워크를 사용하는 개발자가 자신이 기본 설정을
Spring Boot에서 정의한 방식대로만 사용해야 하는 것이 아닌
자신이 원하는 설정으로 커스터마이징할 수 있다는 것을 알아야 하기 때문이다.

만약 @ConditionalOnXXX와 같은 어노테이션이 없다면
'개발자가 직접 구성한 설정'과 '기존 Spring Boot에 설정된 설정'이 충돌하며
오류를 발생시킬 수 있으므로 이런 점을 고려하여 설정 커스터마이징을 할 수 있어야 함을 인지해야 한다.

👣 특정 Bean 제거

실제로 사용해보지 않았지만 ChatGPT에게 특정 설정 Bean을 제거하기 위한 방법을 문의한 결과 다음과 같은 방법이 있다고 알려주었다. 실제로 코드로 사용해보지 않았지만 차후 사용할 경우를 대비해 적어본다.

@SpringBootApplication
// DataSourceAutoConfiguration 비활성화
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
    
}

위와 같이 @EnableAutoConfiguration의 exclude 옵션을 사용하면 특정 Bean을 제거할 수 있다는 사실을 깨달았다.

'Spring Boot' 카테고리의 다른 글

Spring Boot HTTPS 적용  (0) 2023.07.28
Executable Jar  (0) 2023.07.28
application.yml 프로퍼티  (0) 2023.07.27
Spring Boot 버전 관리 원리  (0) 2023.07.27
Servlet에서 Spring Boot까지의 발전 양상  (0) 2023.07.12