Java에서 @Import
주석은 다른 구성 클래스나 Bean을 소개하는 데 사용되는 주석입니다. 이는 특정 구성 클래스나 빈을 Spring 컨테이너에 등록하고 이를 애플리케이션에서 사용할 수 있도록 하는 데 도움이 됩니다.
@Import에 대한 자세한 설명
@Import
@Configuration으로 주석이 달린 클래스나 일반 클래스에서 주석을 사용할 수 있습니다. @ImportResource
, @ImportSelector
등 의 다른 주석을 태그할 수 있는 메타 주석 역할을 합니다 @ImportBeanDefinitionRegistrar
.
주석을 사용하면 @Import
다음을 Spring 컨테이너로 가져올 수 있습니다.
- Configuration Class(Configuration Class): 다른 구성 클래스를 import하여 내부에 정의된 Bean을 컨테이너에 등록할 수 있다.
- 일반 클래스(비구성 클래스): 일반 클래스를 Spring 컨테이너에 Bean으로 가져옵니다.
@소스코드 가져오기
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
주석 관점에서 @Import 주석은 클래스에만 표시할 수 있으며 @Configuration 주석, ImportSelector, ImportBeanDefinitionRegistrar 또는 가져오기 일반 클래스와 함께 사용할 수 있습니다.
따라서 @Import를 사용하는 방법에는 클래스를 직접 가져오는 방법, Bean을 가져올 구성 클래스를 가져오는 방법, ImportSelector의 구현 클래스를 가져오는 방법, ImportBeanDefinitionRegister의 구현 클래스를 가져오는 방법이 있습니다. ImportSelector와 ImportBeanDefinitionRegistrar 두 인터페이스는 함께 사용하려면 @Import에 의존해야 하지만 @Import는 단독으로 사용할 수 있다는 점에 유의해야 합니다.
@Import의 구현 원칙
@Import
주석의 구현 원리에는 구성 요소 검색, Bean 등록 및 Spring 프레임워크의 종속성 주입 메커니즘이 포함됩니다.
-
컴포넌트 스캐닝: Spring 프레임워크는
@Configuration
컴포넌트 스캐닝 메커니즘을 통해 주석 또는 기타 지정된 주석이 있는 구성 클래스를 자동으로 스캔하고 로드하며 이를 구성 클래스로 인식합니다. -
구성 클래스 등록: 구성 클래스가 인식되면 Spring은 이를 Bean으로 인스턴스화하고 컨테이너에 등록합니다. 이러한 방식으로 구성 클래스 내부에 정의된 모든 Bean은 Spring 컨테이너에서 관리될 수 있습니다.
-
주석 처리 :
@Import
구성 클래스에@Import
주석이 사용될 때 Spring은 주석의 매개변수를 구문 분석하고 다양한 유형의 매개변수에 따라 해당 처리를 수행합니다.-
다른 구성 클래스 가져오기:
@Import
매개변수가 다른 구성 클래스(예:@Configuration
주석이 달린 클래스)인 경우 Spring은 가져온 구성 클래스를 컨테이너에 추가하므로 가져온 구성 클래스 내부에 정의된 Bean도 관리할 수 있습니다. -
일반 클래스 가져오기:
@Import
매개변수가 일반 클래스인 경우 Spring은 클래스를 Bean으로 인스턴스화하고 이를 컨테이너에 등록합니다. -
구현된
ImportSelector
클래스 가져오기:@Import
매개변수가 인터페이스를 구현하는 클래스인 경우 Spring은 인터페이스의 메소드를ImportSelector
호출 하고 반환된 클래스 이름 배열에 따라 해당 클래스를 Bean으로 등록합니다. 이런 방식으로 가져와야 하는 클래스를 특정 논리에 따라 동적으로 선택할 수 있습니다.ImportSelector
selectImports()
-
구현된
ImportBeanDefinitionRegistrar
클래스 가져오기: 매개변수가 인터페이스를@Import
구현하는 클래스 인 경우 Spring은 인터페이스의 메소드를 호출 하고 Bean 정의를 프로그래밍 방식으로 컨테이너에 등록합니다. 이러한 방식으로 사용자 정의 로직을 통해 추가 Bean을 등록할 수 있습니다.ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar
registerBeanDefinitions()
-
위의 단계를 통해 주석을 사용하면 다른 구성 클래스, 공통 클래스 또는 인터페이스를 @Import
구현하는 클래스를 쉽게 가져오고 이를 Spring 컨테이너에 등록하여 Bean 관리 및 종속성 주입을 수행할 수 있습니다.ImportSelector
ImportBeanDefinitionRegistrar
임포트해야 하는 클래스
public class HelloImport {
public void test() {
System.out.println("hello JF");
}
}
1. 수업을 직접 가져오기
@Import(HelloImport.class)
public class SpringTestApplication {
public static void main(String[] args) {
//1.通过AnnotationConfigApplicationContext创建spring容器,参数为@Import标注的类
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);
HelloImport helloImport = applicationContext.getBean(HelloImport.class);
elloImport.test();
}
}
다음 방법은 프로젝트에서 일반적으로 사용됩니다.
@Import(HelloImport.class)
@Configuration
public class ConfigTest {
}
2. 구성 클래스 가져오기 및 Bean 주입
@Configuration
public class HelloImportConfiguration {
@Bean
public HelloImport helloImport() {
return new HelloImport();
}
}
@Import(HelloImportConfiguration.class)
public class SpringTestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);
HelloImport helloImport = applicationContext.getBean(HelloImport.class);
helloImport.test();
}
}
이 방법의 사용 시나리오는 구성 클래스를 직접 스캔할 수 없다는 것입니다.
3. ImportSelector 구현 클래스 가져오기
ImportSelector는 인터페이스이며 이 인터페이스를 구현하려면 selectImports 메서드를 다시 작성해야 합니다. selectImports 메소드는 컨테이너로 가져와야 하는 클래스의 정규화된 이름을 요소로 포함하는 문자열 배열을 반환합니다.
public class HelloImportSelector implements ImportSelector {
/**
* 返回需要导入的类名的数组,可以是任何普通类,配置类(@Configuration、@Bean、@CompontentScan等标注的类)
* @importingClassMetadata:用来获取被@Import标注的类上面所有的注解信息
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
List list = new ArrayList<>();
list.add("intl.skw.test.HelloImport");
return StringUtils.toStringArray(list);
}
}
@Import(HelloImportSelector.class)
public class SpringTestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);
HelloImport helloImport = applicationContext.getBean(HelloImport.class);
helloImport.test();
}
}
4. ImportBeanDefinitionRegistrar 구현 클래스 가져오기
클래스가 ImportBeanDefinitionRegistrar 인터페이스를 구현하면 레지스트리를 가져오고, 컨테이너에 Bean을 등록하고, Bean에 속성을 추가할 수 있습니다.
public class HelloImportDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(HelloImport.class)
.getBeanDefinition();
registry.registerBeanDefinition("HelloImport", beanDefinition);
}
}
@Import(HelloImportDefinitionRegistrar.class)
public class SpringTestApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTestApplication.class);
HelloImport helloImport = applicationContext.getBean(HelloImport.class);
helloImport.test();
}
}