스프링 부트의 자동설정(AutoConfiguration)

Sungwoo Hwang·2021년 1월 29일
0

스프링 부트

목록 보기
2/2

본 글은 공부만 하면 까먹을 것 같아서 정리하는 글입니다.

본 글은 인프런 백기선 강사님의 '스프링 부트-개념과 활용' 강좌에서 발췌한 내용들이 포함되어 있습니다.
스프링 부트 버전은 2.4.2 버전 입니다.

@SpringBootApplication

@SpringBootApplication
public class DemoApplication {

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

스프링 부트 프로젝트를 생성하면 가장 먼저 보이는 annotation이 @SpringBootApplication입니다.

@SpringBootApplication은 크게 3가지의 annotation으로 구성되어 있는데 아래와 같습니다.

  • @SpringBootConfiguration
  • @ComponentScan
  • @EnableAutoConfiguration

    @SpringBootApplication = (@SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration )

@SpringBootConfiguration

클래스에 명시하는 annotation으로 클래스가 application의 환경설정을 제공한다고 알려줍니다.

대부분의 스프링 부트는 일반적인 경우에서 @SpringBootConfiguration을 상속한 @SpringBootApplication을 통해 사용합니다.

@ComponentScan

basePackages 혹은 basePackageClass에 별다른 값을 주지 않으면 @ComponentScan annotation이 적용된 클래스의 패키지와 하위 패키지들을 대상으로 @Component, @Repository , @Service , @Controller, @RestController annotation이 사용된 클래스에 대한 스캔을 수행합니다.

xml을 이용해 등록하거나 @Bean 을 사용하지 않고 간편하게 bean을 등록!

@EnableAutoConfiguration

스프링 부트에서는 2단계를 거쳐 bean들이 등록됩니다.
1. @ComponentScan
2. @EnableAutoConfiguration

@ComponentScan@Component annotation을 사용한 클래스들을 bean으로 등록한다는 건 알겠는데, @EnableAutoConfiguration을 사용할 때는 어떤 클래스가 bean으로 등록된다는 것일까요?

@EnableAutoConfigurationEnable은 스프링 부트의 META-INF 파일을 읽어서 미리 정의된 설정파일(@Configuration)을 자동으로 등록할 수 있게 합니다.

미리 정의된 설정파일을 찾아보겠습니다

스프링 부트 프로젝트에 추가된 의존성 중 spring-boot-autoconfigure라는 의존성의 META-INF 파일 안 spring.factories를 보면


org.springframework.boot.autoconfigure.EnableAutoConfiguration라는 key 값과 AutoConfiguration으로 끝나는 많은 value 값들이 있습니다. 이것들이 모두 기본으로 설정되어 있는 AutoConfiguration입니다.

그 중에 한가지인 DispatcherServletAutoConfiguration을 살펴보겠습니다.

// DispatcherServletAutoConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
...
...
}

많은 annotation들이 사용되었지만 주목할 부분은 @Configuration입니
다. 결국 DispatcherServletAutoConfigurationbean을 설정하는 java 설정파일입니다.

spring.factories안에 autoconfigure.EnableAutoConfiguration key에 대응하는 많은 AutoConfiguration 클래스들이 @EnableAutoConfiguration의 대상이 되는 것 입니다.

@Conditional annotation

그러나 모든 AutoConfiguration들이 등록되는 것은 아닙니다.

DispatcherServletAutoConfiguration 파일을 보면 @ConditionalOnClass,
@ConditionalOnMissingBean 과 같은 여러 조건들이 명시되어 있습니다.

이 조건들을 모두 만족해야 @EnablueAutoConfiguration에 의해서 bean으로 등록이 되는 것 입니다.

// DispatcherServletAutoConfiguration.java

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
...
...
}

예를 들어 @ConditionalOnWebApplication(type = Type.SERVLET)라는 부분을 보면 WebApplicationtypeSERVLET일때만AutoConfiguration이 등록이 됩니다.

만약 아래와 같이 WebAppliationTypeNONE으로 수정하고,

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {	
    SpringApplication app=new SpringApplication(DemoApplication.class);
    app.setWebApplicationType(WebApplicationType.NONE);
    app.run(args);
  }
}

AppRunner에서 DispatcherServlet을 가져오려고 하면,

@Component
public class AppRunner implements ApplicationRunner {
	
    @Autowired
    private DispathcerServlet servlet;

    @Override
    public void run(ApplicationArguments args) throws Exception {
		...
        }
}

DispatcherServlet that could not be found. 이라는 오류를 출력합니다.

WebApplicationTypeSERVLET이 아니라 NONE이기 때문에
DispatcherServletAutoConfiguration이 자동으로 등록되지 않고 DispatcherServlet도 bean으로 등록이 되지 않은 것 입니다.

물론 WebApplicationType과 관련없는(@Conditional 조건을 사용하지 않은)
다른 AutoConfiguration들은 자동으로 등록이 되겠죠?

@Conditional을 통해서 특정한 AutoConfiguration자동으로 등록되고 등록되지 않는 것 입니다.

참고한 자료와 출처들

profile
becomeweasel.tistory.com로 이전

0개의 댓글