In Java @Import
sind Annotationen Annotationen, die zur Einführung anderer Konfigurationsklassen oder Beans verwendet werden. Es hilft, bestimmte Konfigurationsklassen oder Beans im Spring-Container zu registrieren und sie der Anwendung zur Verfügung zu stellen.
Detaillierte Erklärung von @Import
@Import
Anmerkungen können für mit @Configuration annotierte Klassen oder für normale Klassen verwendet werden. Es fungiert als Meta-Anmerkung, die andere Anmerkungen wie @ImportResource
, @ImportSelector
usw. markieren kann @ImportBeanDefinitionRegistrar
.
Mithilfe von @Import
Annotationen kann Folgendes in den Spring-Container importiert werden:
- Konfigurationsklasse (Konfigurationsklasse): Durch den Import anderer Konfigurationsklassen können die darin definierten Beans im Container registriert werden.
- Gewöhnliche Klasse (Nicht-Konfigurationsklasse): Importieren Sie gewöhnliche Klassen als Beans in den Spring-Container.
@Quellcode importieren
@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();
}
Aus Annotationssicht kann die @Import-Annotation nur für die Klasse markiert werden und in Verbindung mit der @Configuration-Annotation, ImportSelector, ImportBeanDefinitionRegistrar oder dem Import gewöhnlicher Klassen verwendet werden.
Daher gibt es vier Möglichkeiten, @Import zu verwenden: Klassen direkt importieren, Konfigurationsklassen importieren, um Beans zu importieren, die Implementierungsklasse von ImportSelector importieren und die Implementierungsklasse von ImportBeanDefinitionRegister importieren. Es ist zu beachten, dass beide Schnittstellen, ImportSelector und ImportBeanDefinitionRegistrar, von @Import abhängen müssen, um gemeinsam verwendet zu werden, während @Import allein verwendet werden kann.
Implementierungsprinzip von @Import
@Import
Das Implementierungsprinzip von Annotationen umfasst den Mechanismus des Komponenten-Scannens, der Bean-Registrierung und der Abhängigkeitsinjektion des Spring-Frameworks
-
Komponenten-Scan: Das Spring-Framework scannt und lädt automatisch
@Configuration
Konfigurationsklassen mit Anmerkungen oder anderen angegebenen Anmerkungen über den Komponenten-Scan-Mechanismus und erkennt sie als Konfigurationsklassen. -
Konfigurationsklasse registrieren: Wenn eine Konfigurationsklasse erkannt wird, instanziiert Spring sie als Bean und registriert sie im Container. Auf diese Weise können alle innerhalb der Konfigurationsklasse definierten Beans vom Spring-Container verwaltet werden.
-
Anmerkungen verarbeiten : Wenn Anmerkungen
@Import
für Konfigurationsklassen verwendet werden, analysiert Spring die Parameter der Anmerkungen und führt die entsprechende Verarbeitung entsprechend verschiedenen Parametertypen durch.@Import
-
Andere Konfigurationsklassen importieren: Wenn es
@Import
sich bei dem Parameter um eine andere Konfigurationsklasse handelt (z. B.@Configuration
eine annotierte Klasse), fügt Spring auch die importierte Konfigurationsklasse zum Container hinzu, sodass auch die in der importierten Konfigurationsklasse definierten Beans verwaltet werden können. -
Gewöhnliche Klasse importieren: Wenn
@Import
der Parameter eine gewöhnliche Klasse ist, instanziiert Spring die Klasse als Bean und registriert sie im Container. -
Importieren Sie die implementierte
ImportSelector
Klasse: Wenn@Import
der Parameter eine Klasse ist, dieImportSelector
die Schnittstelle implementiert, ruft Spring die MethodeImportSelector
der Schnittstelle aufselectImports()
und registriert die entsprechende Klasse als Bean gemäß dem zurückgegebenen Klassennamen-Array. Auf diese Weise können die zu importierenden Klassen dynamisch nach einer bestimmten Logik ausgewählt werden. -
Importieren Sie die implementierte
ImportBeanDefinitionRegistrar
Klasse: Wenn@Import
der Parameter eine Klasse ist, dieImportBeanDefinitionRegistrar
die Schnittstelle implementiert, ruft Spring die MethodeImportBeanDefinitionRegistrar
der Schnittstelle aufregisterBeanDefinitions()
und registriert die Bean-Definition programmgesteuert im Container. Auf diese Weise können durch benutzerdefinierte Logik zusätzliche Beans registriert werden.
-
Durch die oben genannten Schritte @Import
ermöglichen uns Annotationen den einfachen Import anderer Konfigurationsklassen, allgemeiner Klassen oder Klassen, die ImportSelector
Schnittstellen implementieren ImportBeanDefinitionRegistrar
, und registrieren sie im Spring-Container, um Bean-Management und Abhängigkeitsinjektion zu erreichen.
Klassen, die importiert werden müssen
public class HelloImport {
public void test() {
System.out.println("hello JF");
}
}
1. Klassen direkt importieren
@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();
}
}
Die folgenden Methoden werden häufig in Projekten verwendet:
@Import(HelloImport.class)
@Configuration
public class ConfigTest {
}
2. Konfigurationsklasse importieren und Bean injizieren
@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();
}
}
Das Verwendungsszenario dieser Methode besteht darin, dass die Konfigurationsklasse nicht direkt gescannt werden kann.
3. Importieren Sie die ImportSelector-Implementierungsklasse
ImportSelector ist eine Schnittstelle, und die Implementierung dieser Schnittstelle erfordert ein Umschreiben der Methode selectImports. Die Methode „selectImports“ gibt ein String-Array zurück, dessen Elemente die vollständig qualifizierten Namen der Klassen sind, die in den Container importiert werden müssen.
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. Importieren Sie die Implementierungsklasse ImportBeanDefinitionRegistrar
Wenn die Klasse die Schnittstelle ImportBeanDefinitionRegistrar implementiert, können Sie die Registrierung abrufen, jedes Bean im Container registrieren und dem Bean Eigenschaften hinzufügen.
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();
}
}