BE/Spring

@SpringBootApplication 이란?

E@st 2023. 8. 10. 05:49

@SpringBootApplication 에는 대표적으로 3개에 어노테이션이 붙어 있습니다.

 

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration 어노테이션

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {

Spring Boot는 애플리케이션 개발을 단순화하는 많은 기능을 제공하는데, 그 중 하나가 @SpringBootConfiguration 어노테이션입니다. 이 어노테이션은 애플리케이션의 주 구성 클래스를 표시하고, 다양한 측면에서 중요한 역할을 수행합니다.

클래스 레벨 어노테이션

@Target(ElementType.TYPE) 는 이 어노테이션이 클래스 수준에서만 사용될 수 있다는 것을 나타냅니다.

런타임 접근 가능

@Retention(RetentionPolicy.RUNTIME)은 어노테이션이 런타임에도 유지되어야 함을 나타내므로, 리플렉션을 통한 동적 처리가 가능합니다.

문서화

@Documented는 이 어노테이션이 문서에 포함되어야 함을 의미합니다(javadoc)

Spring 구성 지원

@Configuration은 @SpringBootConfiguration이 Spring의 기본 구성 클래스임을 나타냅니다. 빈 정의와 함께 Spring 컨테이너가 어떻게 동작해야 하는지를 제어합니다.

검색 성능 최적화

@Indexed는 인덱싱을 활성화하여 클래스 패스에서 빠르게 찾을 수 있게 합니다,

빈 메서드 프록싱

proxyBeanMethods() 메서드 이름이 궁금증을 유발해서 찾아보니 @Bean 메서드가 프록시가 되어야 하는지 여부를 결정한다고 합니다. 즉 true(기본값) 일때는 구성 클래스 내부에서 직접 메서드 호출을 통해 빈 메서드를 사용할 경우 프록시를 이용해 싱글톤을 객체를 반환하고 false일때는 팩토리 메서드처럼 호출마다 새로운 인스턴스가 생겨난다고 합니다.

주의사항

애플리케이션 내에는 단 하나의 @SpringBootConfiguration만 있어야 하며, 일반적으로 @SpringBootApplication에서 상속됩니다.

결론

@SpringBootConfiguration은 Spring Boot 애플리케이션의 구성을 담당하는 특별한 어노테이션입니다. 이는 애플리케이션의 복잡성을 줄이고, 개발자가 중점적으로 비즈니스 로직에 집중할 수 있도록 도와줍니다. 즉, 아래에서 설명할 COmponentScan과 더불어 @Configuration을 스캔할 시작위치 라고 보면될 거 같습니다.

@EnableAutoConfiguration 어노테이션

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

 

@EnableAutoConfiguration 어노테이션은 Spring Boot 애플리케이션에서 중요한 역할을 합니다. 이 어노테이션은 스프링의 애플리케이션 컨텍스트를 자동 구성하려고 시도하며, 필요한 빈을 예측하고 구성합니다. 해당 어노테이션의 주요 부분에 대해 자세히 살펴보겠습니다.

어노테이션의 속성

  • @Target(ElementType.TYPE): 이 어노테이션은 클래스 레벨에서만 사용할 수 있습니다.
  • @Retention(RetentionPolicy.RUNTIME): 런타임 시에도 어노테이션 정보를 유지합니다.
  • @Documented: 문서에 어노테이션 정보가 포함됩니다.
  • @Inherited: 하위 클래스가 어노테이션을 상속할 수 있게 합니다.

동작

  • 자동 구성: Spring Boot의 자동 구성(auto-configuration) 메커니즘을 활성화하며, 이 과정에서 Spring Boot는 spring.factories 파일에서 자동 구성 클래스 목록을 읽어옵니다.
  • 제외 메커니즘: 특정 자동 구성을 적용하지 않기 원한다면 exclude()나 excludeName()을 사용하여 제외할 수 있으며, spring.autoconfigure.exclude 속성을 통해서도 제외할 수 있습니다.

사용 방법과 위치

  • @SpringBootApplication을 사용하면 자동 구성이 자동으로 활성화되므로 이 어노테이션을 별도로 추가할 필요가 없습니다.
  • @EnableAutoConfiguration은 가능한 루트 패키지에 위치해야 하며, 이로써 모든 하위 패키지와 클래스를 검색할 수 있게 됩니다.

주의사항

  • 조건부 빈: 대부분의 자동 구성 빈은 조건부로 생성됩니다. 예를 들어, 특정 클래스가 클래스패스에 있는 경우나 특정 빈이 없는 경우에만 생성됩니다.

결론

@EnableAutoConfiguration은 Spring Boot 애플리케이션의 중심적인 부분으로, 개발자가 일일이 설정할 필요 없이 많은 부분을 자동으로 설정해줍니다. 즉, 이 어노테이션을 활성화 하면 spring.factories 파일에서 구성 클래스 목록을 읽어보고 자동 구성 클래스 목록을 읽어오고 자동설정합니다.

근데 만약에 우리가 정의한 bean과 Spring Boot가 정의한 bean이 충돌이 발생하면 어떻게 될까요? 또는 우리에게 필요하지 않은 설정까지 등록하면 느려지는거 아닐까요?

spring.factories 정보를 가지고 autoConfiguration을 진행하면서 @Conditional 을 참고해서 등록한다. 그리고 해당 조건이 맞지 않을 경우 해당 AutoConfiguration이 동작하지 않도록 제외시키는 역할을 수행합니다.

@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@ImportRuntimeHints(WebResourcesRuntimeHints.class)
public class WebMvcAutoConfiguration {

WebMvcAutoConfiguration 클래스는 @ConditionalOnWebApplication, @ConditionalOnClass, @ConditionalOnMissingBean 등의 어노테이션을 사용하여 조건에 따라 이 자동 구성이 활성화되거나 비활성화됩니다.

@ComponentScan 어노테이션

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

@ComponentScan이란?

스프링 프레임워크의 @ComponentScan 어노테이션은 스프링 애플리케이션 컨텍스트가 자동으로 컴포넌트를 찾을 수 있는 패키지를 지정하는 데 사용됩니다. 이것은 클래스 경로 스캔을 활용하여 지정된 패키지와 하위 패키지에서 컴포넌트(예: @Component, @Service, @Repository, @Controller 등)를 검색하고 스프링 애플리케이션 컨텍스트에 등록합니다.

basePackages와 value

  • basePackages: 스캔할 패키지의 이름을 문자열 배열로 지정합니다.
  • value: **basePackages**와 동일한 기능을 하며, 이 중 하나만 사용할 수 있습니다.

기본 값은 basePackages 으로 되어 있습니다.