2023. 5. 4. 13:35ㆍSpring Boot/Spring Boot Auto Configuration
🌿 Spring @Import 어노테이션 정리
@Import
는 Spring Framework에서 구성(Configuration) 메타데이터를 추가하는 방법 중 하나입니다.
이를 통해 다른 구성 클래스를 로드 하거나, 동적으로 빈을 등록 할 수 있습니다.
사용 방식에 따라 정적(Static) 방법과 동적(Dynamic) 방법으로 나뉩니다.
1️⃣ 정적(Static) 방법: 직접 클래스 지정
가장 기본적인 @Import
사용 방식으로, 한 개 또는 여러 개의 구성 클래스를 직접 명시 합니다.
@Configuration
@Import({ConfigA.class, ConfigB.class})
public class MainConfig {
// ...
}
📌 작동 방식
✅ ConfigA
와 ConfigB
에 정의된 빈들이 Spring 컨텍스트에 등록
✅ 컴파일 시점에 결정되므로 정적인 방법
2️⃣ 동적(Dynamic) 방법: ImportSelector & ImportBeanDefinitionRegistrar 사용
동적 방법에서는 구성 클래스를 프로그래밍 방식으로 결정하여 등록 할 수 있습니다.
✨ (1) ImportSelector 사용
ImportSelector
의 selectImports()
메서드를 구현하여 등록할 클래스 목록을 동적으로 반환 합니다.
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] {
"com.example.config.ServiceConfigA",
"com.example.config.ServiceConfigB"
};
}
}
📌 작동 방식
✅ selectImports()
메서드에서 등록할 설정 클래스의 FQCN(완전한 클래스명)을 반환
✅ @Configuration
이나 @Component
가 적용된 클래스들을 스프링 컨텍스트에 추가
✅ 특정 조건에 따라 다른 클래스를 등록 가능 → 유연한 설정 가능
🛠 사용 예제
@SpringBootApplication
@Import(MyImportSelector.class) // ImportSelector 등록
public class ImportSelectorApplication implements CommandLineRunner {
private final ApplicationContext context;
public ImportSelectorApplication(ApplicationContext context) {
this.context = context;
}
public static void main(String[] args) {
SpringApplication.run(ImportSelectorApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println("Bean serviceA: " + context.getBean("serviceA"));
System.out.println("Bean serviceB: " + context.getBean("serviceB"));
}
}
🛠 실행 결과
Bean serviceA: Service A Bean
Bean serviceB: Service B Bean
✨ (2) ImportBeanDefinitionRegistrar 사용
ImportBeanDefinitionRegistrar
는 Spring 컨텍스트에 빈을 프로그래밍 방식으로 등록 할 수 있습니다.
이 방식은 더 정밀한 제어가 필요할 때 사용됩니다.
📌 주요 메서드
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition("customService")) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(CustomService.class);
registry.registerBeanDefinition("customService", beanDefinition);
System.out.println("customService 빈 등록 완료");
}
}
}
📌 작동 방식
✅ registerBeanDefinitions()
에서 Spring 컨텍스트에 동적으로 빈을 등록
✅ 특정 조건에 따라 빈을 등록 가능
✅ 기존 빈이 등록되어 있는지 확인 후, 중복 방지 가능
🛠 사용 예제
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(MyImportBeanDefinitionRegistrar.class)
public @interface EnableMyFeature {
}
@SpringBootApplication
@EnableMyFeature // 커스텀 애노테이션 사용
public class ImportBeanDefinitionRegistrarApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(ImportBeanDefinitionRegistrarApplication.class, args);
CustomService customService = context.getBean(CustomService.class);
customService.performAction();
}
}
🛠 실행 결과
customService 빈 등록 완료
Performing custom service action
3️⃣ ImportSelector vs. ImportBeanDefinitionRegistrar 비교
기능 | ImportSelector | ImportBeanDefinitionRegistrar |
---|---|---|
클래스 등록 방식 | 구성 클래스(@Configuration) 자체를 등록 | 구성 클래스 외에도 개별 빈 정의 등록 가능 |
리턴 타입 | 클래스명(String 배열) | BeanDefinitionRegistry를 이용해 직접 등록 |
유연성 | 상대적으로 제한적 | 더 정밀한 제어 가능 |
주 사용 목적 | 특정 환경에 따라 설정 클래스를 동적으로 로드 | 복잡한 빈 설정, 런타임에 등록 |
📌 ImportSelector 는 설정 클래스 를 동적으로 가져오는 데 사용
📌 ImportBeanDefinitionRegistrar 는 구체적인 빈 정의를 직접 등록 가능
4️⃣ 응용 사례
✅ 정적 구성(@Import)
@Configuration
클래스를 명시적으로 불러와 컴파일 시점에 결정된 설정 클래스 등록
✅ ImportSelector
- 특정 조건에 따라 어떤 설정 클래스를 로드할지 결정 (예: 환경별 설정)
✅ ImportBeanDefinitionRegistrar
- 특정 상황에서 별도의 빈을 수동으로 등록 (예: 외부 라이브러리 지원)
🎯 결론
🔹 @Import
를 사용하면 정적/동적 방식으로 구성 클래스를 스프링 컨텍스트에 등록 가능
🔹 ImportSelector
는 설정 클래스 자체를 동적으로 등록
🔹 ImportBeanDefinitionRegistrar
는 개별 빈을 정밀하게 등록 가능
🔹 애플리케이션 요구사항에 따라 적절한 방법을 선택하여 활용 가능 🚀
'Spring Boot > Spring Boot Auto Configuration' 카테고리의 다른 글
@EnableAutoConfiguration (0) | 2024.10.16 |
---|---|
@SpringBootConfiguration (0) | 2024.10.16 |
SpringApplication.run (0) | 2024.10.16 |
@SpringBootApplication (0) | 2024.10.16 |
Classpath (0) | 2024.10.16 |