상세 컨텐츠

본문 제목

Spring Boot의 Config Annotation 에 대해 알아보자

IT/프로그래밍

by James Lee. 2019. 3. 3. 17:03

본문

스프링을 써본 개발자라면, Spring 환경설정을 하다 진이 빠진 경험이 한 두번 쯤은 있을 것이다.

스프링 부트는 어떻게 이러한 설정이 없이 동작이 가능한 것일까?

스프링 부트는 여러 자주 사용되는 설정들이 기본적으로 잡혀 있다.

스프링 부트의 시작점인 Application 클래스는 보통 아래와 같은 구조를 가지고 있다.

(Spring Boot 2.x에서는 @SpringBootApplication 을 사용한다.)

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).run(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

스프링에서 관리하는 POJO(Plain Old Java Object)를 '빈(Bean)'이라 한다.

@ComponentScan 어노테이션은 현재 패키지 이하에서 @Component 어노테이션이 붙어 있는 클래스들을 찾아서 빈으로 등록하는 역할을 한다.

@Controller
public class XXController {
    //...
}

Spring MVC 에서 자주 사용되는 @Controller 어노테이션도 내부를 까보면 이 @Component 를 가지고 있는 것을 확인할 수 있다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";

}

심지어 설정 파일 어노테이션인 @Configuration 자체도 @Component이다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

설정 자동 등록하기 - @EnableAutoConfiguration

@EnableAutoConfiguration 은 Spring Boot의 핵심으로써, 미리 정의되어 있는 빈들을 가져와서 등록해준다.

요 녀석도 @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 { 

@EnableAutoConfiguration

public @interface EnableAutoConfiguration {

    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

그렇다면 기본적으로 설정되어 있는 빈들은 어디에 정의되어 있는 것일까?

그 빈들은 외부 라이브러리(External Libraries)중 spring-boot-autoconfigure에 정의되어 있다.

이 중 META-INF 디렉토리 하위의 spring.factories 파일에 자동으로 가져올 Bean들이 정의되어 있다.

AOP와 같은 각종 스프링의 설정들이 기본으로 잡혀 있는 것을 볼 수 있다. 위에 설정 정의가 기본적으로 되어 있고, 우리가 해당 의존성을 설치했을 때 위의 설정대로 적용이 되는 것이다.

...
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
...

이 중 org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration 이라는 녀석은 디스패쳐 서블릿을 정의해주는 설정 파일이다.

DispatcherServletAutoConfiguration.java 파일을 열면 아래와 같이 되어 있다.

(org.springframework.boot.autoconfigure.web 패키지에 있다.)

@AutoConfigureOrder(-2147483648)
@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({DispatcherServlet.class}) //DispatcherServlet 일 때만 해당 설정이 적용 됨
@AutoConfigureAfter({ServletWebServerFactoryAutoConfiguration.class})
public class DispatcherServletAutoConfiguration {
    public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
    public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";

    public DispatcherServletAutoConfiguration() {
    }

이러한 설정 구조를 파악하고 나면, 사용자가 빈을 재정의 할 수 있다.

원하는대로 커스터마이징이 가능하게 된다는 말이다.

  • ex) 디스패처 서블릿을 사용자가 재정의 할 수 있다.


관련글 더보기

댓글 영역