본문 바로가기
Spring/인프런 토비의 Spring Boot

섹션 6-5 [자동 구성 기반 애플리케이션] 동적인 자동 구성 정보 등록

by include_hoany 2024. 6. 15.

동적인 자동 구성 정보 등록

package com.tobyspring.config;  
  
import com.tobyspring.config.autoconfig.DispatcherServletConfig;  
import com.tobyspring.config.autoconfig.TomcatWebserverConfig;  
import org.springframework.context.annotation.Import;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@Import({DispatcherServletConfig.class, TomcatWebserverConfig.class})  
public @interface EnableMyAutoConfiguration { }

기존에 합성 애노테이션 EnableMyAutoConfiguration DispatcherServletConfg, TomcatWebServerConfig을 하드코딩하여 @Import하였습니다. Config class가 적다면 하드코딩을 해도 문제가 없겠지만 추가되거나 제거될때마다 @Import코드를 계속해서 수정해야한다는 문제가 발생합니다. 이러한 문제를 해결하기위 동적으로 class정보를 가져오도록 코드를 수정해보겠습니다.

 

//  
// Source code recreated from a .class file by IntelliJ IDEA  
// (powered by FernFlower decompiler)  
//  
  
package org.springframework.context.annotation;  
  
import java.util.function.Predicate;  
import org.springframework.core.type.AnnotationMetadata;  
import org.springframework.lang.Nullable;  
  
public interface ImportSelector {  
    String[] selectImports(AnnotationMetadata importingClassMetadata);  
  
    @Nullable  
    default Predicate<String> getExclusionFilter() {  
        return null;  
    }  
}

 

동적으로 Config구성정보를 가져오려면 기존에 사용한 @Import 애노테이션으로는 불가능하고 ImportSelector를 사용해야합니다. selectImports 반환 String 배열에 Config class의 이름을 리턴하면 Spring Container가 이름에 해당하는 클래스들을 구성정보로 사용하게 됩니다. 실질적으로 코드를 작성할때는 ImportSelector를 상속한 DeferredImportSelector 인터페이스를 구현하여 구성정보를 동적으로 구성해보도록 하겠습니다.

 

package com.tobyspring.config;  
  
import org.springframework.context.annotation.DeferredImportSelector;  
import org.springframework.core.type.AnnotationMetadata;  
  
/*  
    DeferredImportSelector을 구현하여 config class의  
    이름을 selectImports 메소드를 통해 Sring배열로 리턴합니다.  
 */
 public class MyAutoConfigImportSelector implements DeferredImportSelector {  
    @Override  
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {  
        return new String[] {  
                "com.tobyspring.config.autoconfig.DispatcherServletConfig",  
                "com.tobyspring.config.autoconfig.TomcatWebserverConfig"  
        };  
    }  
}

구성정보를 등록하고자 하는 클래스의 이름을 Spring 배열로 리턴할 수 있도록 구현합니다.

 

package com.tobyspring.config;  
  
import org.springframework.context.annotation.Import;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
@Import(MyAutoConfigImportSelector.class)  
public @interface EnableMyAutoConfiguration { }

그리고 @Import할때 구성정보를 등록할 클래스를 MyAutoConfigImportSelector.class하나만 등록하면 selectImports 메소드를 구현하여 리턴되는 클래스 이름을 바탕으로 구성정보를 등록하게 됩니다.