Programming/Spring Boot

Spring Boot AutoConfiguration

Cloud Applicaiton Architect 2021. 7. 7. 19:49
반응형

서두

Spring Framework를 쓰다 Spring Boot를 접하게 되면 환경 설정과 관련 몇 가지 벽에 맞닥뜨리게 됩니다. Spring Framework을 쓸 때 그렇게 많이 사용하던 xml이 더 이상 쓰이지 않기 때문인데요, 그렇다 치더라도 환경 설정을 담당하던 annotation이 어떻게 동작하는지 감을 잡기 어렵습니다.

이번 포스팅에서는 Spring Boot의 이러한 환경 설정에 대해 알아 보고자 합니다.

Spring Boot는 다음의 여섯 가지 annotation을 @SpringBootApplication이라는 하나의 annotation으로 대체하고 있습니다.

@Tareg(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type=FilterType.CUSTOM, classes = TypeExecludeFilter.class),
@Filter(type=FilterType.CUSTOM, classes=AutoConfigurationExecludeFilter.cclas) } )

public @Interface SpringAppication {

    …
}

개요

  • classpath, beans, config properties를 통해 dependencies를 추적할 수 있는 매커니즘
  • Spring Bean configuration task에 소요되는 개발자 시간 감소
  • e.g. maven이나 gradle에 mysql library dependency가 추가 되어 있다면 application.properties 파일내 mysql jdbc가 설정되어 있지 않더라도 spring-boot의 기본 값을 통해 mysql에 자동 접속 시도(spring-boot-autoconfigure-x.x.x.RELEASE.jar 파일의 META-INF 폴더내 spring.factories 파일 내에 정의)
  • @EnableAutoConfiguration annotation을 통해 동작

  • Exclude시에는 @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, RedisAutoConfiguration.class}) 처럼 사용

Spring Boot 설정 관련 Annotation

@ComponentScan

Spring에서 @Component라는 annotation이 적힌 빈(Bean) 즉 POJO(Plan Old Java Object)들을 자동으로 스켄해서 등록 하는 기능을 담당합니다. Annotation의 원형 클래스 내에 @Component가 지정되어 있더라도 Scan의 대상이 됩니다. 예를 들어 @Controller annotation의 클래스 내부에는 @Component가 선언되어 있습니다.

@EnableAutoConfiguration

Spring Boot의 @EnableAutoConfiguration은 maven이나 gradle의 의존성(dependency/compile) 관계에 있는 jar 파일을 기반으로 Configuration을 자동 설정하는 것을 의미합니다. 예를 들어 kafka나 mongodb가 Dependency에 있다면 다른 특별한 시도를 하지 않아도 kafka나 monogodb에 접속 하려는 시도를 할 것 입니다. 이렇게 @EnableAutoConfiguration이 자동으로 등록하려는 빈들의 목록은 spring-boot-autoconfigure-2.x.x.RELEASE.jar 파일의 META-INF 폴더내 spring.factories 파일 내에 정의 되어 있습니다.

사용자 정의 AutoConfiguration 

Maven이나 Gradle을 이용해 사용자 정의 스프링설정 빈을 만들 수 있습니다. maven 기준 다음의 정보를 추가 합니다.

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure-processor</artifactId>
    <optional>true</optional>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.1.1.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

그리고 작성중인 프로젝트의 resources 디렉토리에 META-INF를 만들고 spring.factories 파일을 만듭니다. 그리고 AutoConfig를 하고 싶은 클래스 명을 다음과 같은 룰로 적어 둡니다.

# spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yourcompany.YourAutoConfig

그리고 클래스는 다음과 같은 예로 작성해 보겠습니다.

package com.yourcompany;

public class Test {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Test{name='" + name + "'}";
    }
}
package com.yourcompany;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class YourAutoConfig {

    @Bean
    public Test test(){
        Test test = new Test();
        test.setName("EDL");
        return test;
    }
}

위와 같이 작성하고 @EnableAutoConfiguration 어노테이션을 추가하면 프로젝트 내의 spring.factories의 설정정보를 읽어와 @Configuration annotation이 추가된 클래스를 찾아 컨테이너에 자동으로 추가합니다.

 

개발자 입장에서 모두 자동화된 설정이 필요하지 않을 때도 있습니다. 이럴 때는 exclude 옵션을 사용해서 해당 라이브러리의 자동 설정은 회피 할 수 있습니다.

아래의 소스는 제가 최근에 분석하고 있는 OSS 기반 프레임워크의 일부 입니다.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;

@SpringBootApplication
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,
                             DataSourceTransactionManagerAutoConfiguration.class, RedisAutoConfiguration.class})
public class EventuateCdcServiceMain {
    public static void main(String[] args) {
        SpringApplication.run(EventuateCdcServiceMain.class, args);
    }
}

위 예제에서 redis, jdbc 관련 auto-configuration이 배제 되어 있는 것을 볼 수 있습니다.

지금까지 설명한 내용을 정리해 보면,

SpringBoot에서는 자주쓰는 컴포넌트들에 대해 환경설정을 @Component라는 annotation이 추가된 클래스를 통해 자동으로(auto scan) 시스템에 등록하게 했으며 기본으로 등록되는 환경 설정 정보(많이 사용되는)는 spring-boot-autoconfigure-2.x.x.RELEASE.jar 내부의 spring.factories 파일에 어떤 Configuration 클래스를 사용지를 지정해 두었습니다. 물론 사용자 지정 클래스도 동일하게 지정해 사용 할 수 있습니다.

오늘 포스팅은 여기까지 하도록 하겠습니다.

감사합니다.

반응형