Programming/Spring

[스프링/Spring] @SpringBootApplication 어노테이션을 완벽하게 파헤쳐보자

예민한고라니 2023. 1. 9. 15:36
0. 목차
1. 서론
2. 본론
  @SpringBootConfiguration
  @ComponentScan
  @EnableAutoConfiguration
3. 정리


서론

스프링부트 프로젝트를 생성을 하게되면, 기본 application클래스가 생성이된다. 해당 클래스를 잘 살펴보면 @SpringBootApllication 어노테이션이 달려있음을 확인 할 수 있다!

 

 

아무생각 없이 당연히 달려있으니까 쓰던 어노테이션이지만, “SpringBootApplication 어노테이션을 사용하면 마법과 같은 일들이 발생한다”고 표현을 할만큼 중요한 역할을 수행한다.

본 게시글에서는 @SpringBootApplication 어노테이션에 대해 파고들어 보겠다


본론

우선 파고들어가보면, 스프링부트어플리케이션 어노테이션의 내부는 다음과 같이 생겼다.

/**
 * Indicates a {@link Configuration configuration} class that declares one or more
 * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
 * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
 * annotation that is equivalent to declaring {@code @Configuration},
 * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
 *
 * @author Phillip Webb
 * @author Stephane Nicoll
 * @author Andy Wilkinson
 * @since 1.2.0
 */
@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 {
...
..

중요한 어노테이션 3가지는 후술하도록하고, 앞의 어노테이션 4개에 대해 간단하게 이야기 해보자.

@Target 는 해당 어노테이션이 사용가능한 범위에 대해 설정해주고

@Retention 어노테이션은 실제 어노테이션이 적용되고 유지되는 범위를 설정해준다.

@Documeted는 소스코드의 코드문서 생성에 도움을 주는 javadoc 이라는 것에 어노테이션 정보를 표현하라는 의미이고

@Inherited는 자식클래스의 어노테이션 상속 여부를 의미한다.

이제 핵심 어노테이션 3가지에 대해 이야기 해보자

@SpringBootConfiguration

Spring에서는 스프링 컨테이너(spring container)라는것을 통해 객체를 관리하는데, 이때 관리되는 객체를 빈(Bean)이라고 표현한다.

@SpringBootConfiguration 어노테이션은 @Bean 정의 메소드를 빈으로 등록하고 사용하는데에 도움을 주는 어노테이션이다.

@SpringBootConfiguration
public class Application {

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

    @Bean
    public PersonService personService() {
        return new PersonServiceImpl();
    }
}

즉, @SpringBootConfiguration 어노테이션이 붙어있는 클래스를 스프링부트에 대한 설정정보가 담긴 클래스로 인식하고, 해당클래스 내부에 @Bean 어노테이션이 담긴 메소드를 찾아 빈을 등록하고 생성해주며 싱글톤 패턴을 유지할 수 있도록 돕는 역할을 한다.

 

💡 @Bean 어노테이션 만으로는 등록이 불가능할까?

사실 @Bean 어노테이션만으로도 빈 등록은 가능하다. 하지만 Configuration 어노테이션이 존재하지 않는다면 싱글톤을 보장받을 수 없다. 싱글톤 패턴의 보장은 spring에서 중요한 개념이므로 이는 다른 게시글에서 후술하겠다!

 

사실 설명만 보게된다면, @Configuration 어노테이션과 동일한 역할을 하는것을 알 수 있는데, @SpringBootConfiguration을 사용하는 이유는 무엇일까에 대해 궁금해졌다.

결론적으로 이야기 해보자면, @SpringBootConfiguration은 @Configuration의 특수화된 버전이라고 한다.

@Configuration과 달리 하나의 어플리케이션은 하나의 @SpringBootConfiguration만을 가질 수 있으며, @SpringBootTest에서 추가적인 이점이 존재한다고 한다.

이와 관련된 자세한 이야기는 링크 에서 확인해볼 수 있으며, 추후에 다른 게시글로 정리해보겠다!

 

@ComponentScan

@ComponentScan 어노테이션은 @Component 어노테이션이 달린 class들은 자동으로 스캔하여 application context에 빈으로 등록해주는 역할을 한다.

💡 @Service나 @Repository 또는 @Controller 어노테이션이 달린 클래스는 어떻게 빈으로 등록될까?

정답은 바로 해당 어노테이션들 내부에 @Component 어노테이션이 존재하기 때문이다.
이런 어노텐이션들을 `stereotype` 어노테이션이라고 부른다

 

@EnableAutoConfiguration

@EnableAutoConfiguration 어노테이션은 스프링 부트의 마법같은 기능auto-configuration을 가능하도록 하는 어노테이션이다.

그렇다면 auto-configuration이란 뭘까?

 

spring 기반 애플리케이션에는 수많은 configuration이 필요하다. 예를들어 보자면

  • spring mvc를 사용할때 컴포넌트 스캔, dispatcher servlet, web jar등을 구성한다던가
  • Hibernate/JPA 사용을 위해 data source, entity manager, transaction manager를 구성한다던가
  • 등등 …

기존의 Spring 에서는 이를 직접 XML파일을 작성하여 configuration을 해주었어야했다.

말로는 쉬워보이지만, 이 작업은 미친듯이 복잡하고 귀찮은 작업이라고 한다.

(궁금하다면 spring mvc configuration xml을 검색(클릭) 하여 찾아보자…)

 

하지만 Spring Boot 에서는 CLASSPATH에 spring MVC나 Hibernate등에 대한 Jar파일이 존재하면,

자동으로 configuration 해주는 어마무시한 기능을 제공하고, 그 기능을 가능토록 하는게 바로 이 어노테이션 인것이다.

이런 스프링 부트의 기능을 가지고 사람들은 마법같다고 표현한다.


정리

@SpringBootApplication 어노테이션은 총 3가지의 중추적인 역할을 하는 어노테이션으로 구성되어있다.

@SpringBootConfiguration

  • 스프링빈을 생성하는 configuration 파일임을 명시하는 역할
  • 싱글톤으로 스프링빈이 등록되도록 도와준다.

@ComponentScan

  • Component 어노테이션이 달린 class 들을 자동 스캔하여, application context에 스프링빈으로 등록되도록 도와준다

@EnableAutoConfiguration

  • Classpath에 존재하는 Jar파일을 자동으로 configuration 해준다.
  • 즉, spring 설정을 위해 수동으로 했어야 했던 수많은 configuration을 자동으로 해주는 것 (auto-configuration)

참고자료

https://www.baeldung.com/springbootconfiguration-annotation

https://www.baeldung.com/spring-componentscan-vs-enableautoconfiguration

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/SpringBootConfiguration.html

https://stackoverflow.com/questions/69851544/what-does-it-mean-by-springbootconfiguration-allows-the-configuration-to-be-fou