Spring Framework 组件注册 之 @Import
2020-12-13 04:44
标签:contex public import 迷茫 close ring 知识点 ext 控制 写在前面 向spring中注册组件或者叫javaBean是使用spring的功能的前提条件。而且spring也提供了很多种方式,让我们可以将普通的javaBean注册到spring容器中,比如前一篇文章Spring Framework 组件注册 之 @Component中写的利用 使用 在spring启动引导类中,添加 spring容器启动后,控制台打印的结果: context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c 通过简单使用 使用 spring容器启动后,配置类中的注解同样会被注册到spring容器中: context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c 由结果可以看出,此时注册的组件名称即为配置类中指定的组件名称,并且通过配置类,可以一次导入多个组件。 在 自定义实现 spring容器启动后,控制台打印的结果: context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81 由结果可以看出, 在 自定义实现 spring容器启动后,控制台打印的结果: context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81 由此可以看出, 上面的例子中分别说明了使用 spring容器启动后,控制台打印的结果: context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81 向spring容器中注册组件的方式有很多,本文主要说明了如何使用 学习永远都不是一件简单的事情,可以有迷茫,可以懒惰,但是前进的脚步永远都不能停止。 不积跬步,无以至千里;不积小流,无以成江海; Spring Framework 组件注册 之 @Import 标签:contex public import 迷茫 close ring 知识点 ext 控制 原文地址:https://blog.51cto.com/8950379/2416136
@Component
注解将普通的javaBean注册到容器中,本文说的@Import
注解也是spring Framework提供的将普通javaBean注册到容器中,以及后续文章会说的@Configuration
,FactoryBean
等方式。@Import 注册普通Bean
@Import
注册一个普通Bean,只需要在@Import
注解中指定待注册Bean的class即可/**
* 使用Import注解,注册一个普通的Bean
*/
@Data
public class TestImport {
private String id = "@Import";
}
@Import
注解/**
* spring 容器启动引导类
*/
@Import(TestImport.class)
public class TestImportBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TestImportBootstrap.class);
System.out.println("context id : " + applicationContext.getId());
String[] beanNames = applicationContext.getBeanNamesForType(TestImport.class);
System.out.println("Bean Name is : " + Arrays.toString(beanNames));
TestImport bean = applicationContext.getBean(TestImport.class);
System.out.println("TestImport bean : " + bean);
applicationContext.close();
}
}
Bean Name is : [com.spring.study.ioc.register.TestImport]
TestImport bean : TestImport(id=@Import)@Import
注解,便可以将一个普通的javaBean注册到spring容器中。并且我们可以看到,通过@Import
注解默认注册的组件名称为该javaBean的全类名@Import 导入 配置类
@Import
注解导入配置类,就会将配置类中的所有组件注册到spring容器中。在spring中,并不是@Configuration
标注的类才是配置类,但是被@Configuration
标注的类会被生成代理对象,spring注入时与不使用@Configuration
注解有很大区别,后续会单独说明此处内容,本文不在赘述。/**
* spring组件配置类
*/
//@Configuration 使用@Import导入时,此注解可以不加
public class TestConfiguration {
@Bean
public TestImport testImport() {
return new TestImport();
}
@Bean
public TestImport testImport2() {
return new TestImport();
}
}
@Import
注解中指定待导入的配置类/**
* spring 容器启动引导类
*/
@Import(TestConfiguration.class)
public class TestImportBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TestImportBootstrap.class);
System.out.println("context id : " + applicationContext.getId());
String[] beanNames = applicationContext.getBeanNamesForType(TestImport.class);
System.out.println("Bean Name is : " + Arrays.toString(beanNames));
TestImport bean = (TestImport) applicationContext.getBean("testImport");
System.out.println("TestImport bean : " + bean);
applicationContext.close();
}
}
Bean Name is : [testImport, testImport2]
TestImport bean : TestImport(id=@Import)@Import 通过ImportSelector 注册
ImportSelector
接口中只定义了一个接口selectImports
,通过此接口返回需要注册的JavaBean的全类名数组,在使用@Import
导入时,会将接口返回的所有类注册到spring容器中/**
* 通过 ImportSelector 接口注册组件
*/
@Data
public class TestSelector {
private String id = "@Import:ImportSelector";
}
ImportSelector
接口/**
* 自定义组件选择器,通过返回需要注册的bean的全类名,进行快速的在IOC容器中注册组件
*/
public class CustomImportSelector implements ImportSelector {
/**
* @param importingClassMetadata 标注了@Import配置类上面所有的注解信息
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{TestSelector.class.getName()};
}
}
@Import
注解中指定ImportSelector实现类/**
* spring 容器启动引导类
*/
@Import(CustomImportSelector.class)
public class TestImportBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TestImportBootstrap.class);
System.out.println("context id : " + applicationContext.getId());
TestSelector bean = applicationContext.getBean(TestSelector.class);
System.out.println("TestSelector bean : " + bean);
String[] beanNames = applicationContext.getBeanNamesForType(TestSelector.class);
System.out.println("bean names:" + Arrays.asList(beanNames));
applicationContext.close();
}
}
TestSelector bean : TestSelector(id=@Import:ImportSelector)
bean names:[com.spring.study.ioc.register.TestSelector]TestSelector
被注册到了spring容器中。与前面的直接注册相比,并没有看出ImportSelector
接口的突出特性。本文只是简单的说明ImportSelector
接口具有注册组件的功能,对于spring容器在启动时,如何执行BeanDefinitionRegistryPostProcessor
来调用selectImports
方法;如何使用ImportSelector
接口实现更复杂的注册功能,将在后续文章中深入理解。@Import 通过ImportBeanDefinitionRegistrar 注册
ImportBeanDefinitionRegistrar
接口中只定义了一个registerBeanDefinitions
方法,在此方法中,可以获取到BeanDefinitionRegistry
对象,利用此对象,即可手动将需要的组件注册的spring容器中。在使用BeanDefinitionRegistry
对象时,还可以指定组件在spring容器中注册的bean名称。/**
* 通过 ImportBeanDefinitionRegistrar 接口手动注册组件
*/
@Data
public class TestRegistrar {
private String id = "@Import:TestRegistrar";
}
ImportBeanDefinitionRegistrar
接口/**
* 手动注册组件到IOC容器中
*/
public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata 标注了@Import配置类上面所有的注解信息
* @param registry BeanDefinition注册器,可以通过此registry手动的向容器中注册指定的组件
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition("testRegistrar")) {
BeanDefinition definition = new RootBeanDefinition(TestRegistrar.class);
registry.registerBeanDefinition("testRegistrar", definition);
}
}
}
@Import
注解中指定ImportBeanDefinitionRegistrar实现类/**
* spring 容器启动引导类
*/
@Import(CustomImportBeanDefinitionRegistrar.class)
public class TestImportBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TestImportBootstrap.class);
System.out.println("context id : " + applicationContext.getId());
TestRegistrar bean = applicationContext.getBean(TestRegistrar.class);
System.out.println("TestRegistrar bean : " + bean);
String[] beanNames = applicationContext.getBeanNamesForType(TestSelector.class);
System.out.println("bean names:" + Arrays.asList(beanNames));
applicationContext.close();
}
}
TestRegistrar bean : TestRegistrar(id=@Import:TestRegistrar)
bean names:[testRegistrar]TestRegistrar
被注册到了spring容器中。与ImportSelector
接口一样,在spring容器启动时,通过BeanDefinitionRegistryPostProcessor
来执行接口方法。@Import同时指定多种接口注册
@Import
,通过直接导入Bean class,配置类,ImportSelector
接口,ImportBeanDefinitionRegistrar
接口来向spring容器中注册组件。当然在使用@Import
注解时,可以同时指定上面的任意几种方式进行注册/**
* spring 容器启动引导类
*
* @author TangFD
* @since 2019/6/25.
*/
@Import({
TestComponent.class,
TestConfiguration.class,
CustomImportSelector.class,
CustomImportBeanDefinitionRegistrar.class
})
public class TestImportBootstrap {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(TestImportBootstrap.class);
System.out.println("context id : " + applicationContext.getId());
String[] beanNames = applicationContext.getBeanDefinitionNames();
System.out.println("bean names:" + Arrays.asList(beanNames));
applicationContext.close();
}
}
bean names:[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, testImportBootstrap, com.spring.study.ioc.register.TestComponent, com.spring.study.ioc.register.TestConfiguration, testImport, testImport2, com.spring.study.ioc.register.TestSelector, testRegistrar]总结
@Import
注解向spring容器中注册组件。并且遗留了一个需要深入理解的知识点:在spring容器启动时,如何通过执行BeanDefinitionRegistryPostProcessor
来执行ImportSelector
和ImportBeanDefinitionRegistrar
接口方法进行组件注册。此处内容,将在后续的spring容器启动过程中,分析BeanFactoryPostProcessor
接口执行过程里进行补充。
下一篇:php取得当前时间函数
文章标题:Spring Framework 组件注册 之 @Import
文章链接:http://soscw.com/essay/29856.html