Spring Framework 组件注册 之 @Import
Spring Framework 组件注册 之 @Import
写在前面
向spring中注册组件或者叫javaBean是使用spring的功能的前提条件。而且spring也提供了很多种方式,让我们可以将普通的javaBean注册到spring容器中,比如前一篇文章Spring Framework 组件注册 之 @Component中写的利用
@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"; }
在spring启动引导类中,添加@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(); } }
spring容器启动后,控制台打印的结果:
context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c
==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(); } }
spring容器启动后,配置类中的注解同样会被注册到spring容器中:
context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@21b8d17c
==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(); } }
spring容器启动后,控制台打印的结果:
context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
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(); } }
spring容器启动后,控制台打印的结果:
context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
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(); } }
spring容器启动后,控制台打印的结果:
context id : org.springframework.context.annotation.AnnotationConfigApplicationContext@238e0d81
==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==]
总结
向spring容器中注册组件的方式有很多,本文主要说明了如何使用@Import
注解向spring容器中注册组件。并且遗留了一个需要深入理解的知识点:在spring容器启动时,如何通过执行BeanDefinitionRegistryPostProcessor
来执行ImportSelector
和ImportBeanDefinitionRegistrar
接口方法进行组件注册。此处内容,将在后续的spring容器启动过程中,分析BeanFactoryPostProcessor
接口执行过程里进行补充。
学习永远都不是一件简单的事情,可以有迷茫,可以懒惰,但是前进的脚步永远都不能停止。
不积跬步,无以至千里;不积小流,无以成江海;
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring Framework 组件注册 之 @Component
Spring Framework 组件注册 之 @Component 写在前面 在spring大行其道的今天,对于spring的使用和掌握乃是不可缺少的必备技能。但是spring的整个体系尤为庞大,对它的学习,还得从基础一点一滴的慢慢积累。本文主要介绍@Component注解在spring中的简单使用,以及注解的派生性和层次性 @Component 简单使用 @Component注解是一个元注解,即可以标注在其它的注解上。在spring中,任何被@Component注解标识的组件均为组件扫描的候选对象,并且被@Component元注解标注的注解,在任何组件标注它时,也被视作组件扫描的候选对象。简单来说,就是在spring中,一个普通的javaBean被@Component注解标记后,在使用基于注解配置和类路径扫描时,会被作为候选组件,添加到spring容器中 package com.spring.study.ioc.register; /** * spring扫描的候选组件 * * @author TangFD * @since 2019/6/25. */ @Data @Compone...
- 下一篇
可解释的机器学习
原文标题 |Interpretable Machine Learning 作者 |Parul Pandey 译者 |intelLigenJ(算法工程师)、鸢尾 编辑 | 王立鱼 原文链接: https://towardsdatascience.com/interpretable-machine-learning-1dec0f2f3e6b 图源Pexels的Pixabay 是时候摆脱黑盒模型,构建起对机器学习的信任了! 想象你是一个数据科学家,你想要在业余时间根据你朋友在facebook和twitter上发布的信息,来预估你朋友假期要去度假的地方。如果你预测对了,你朋友一定叹为观止,觉得你是锦鲤附身。如果你猜错了也没啥,只不过有点影响身为数据科学家的口碑而已。但如果你和其他人打了赌,就赌这个朋友暑假会去哪里,这时候预测错误的成本就有点高了。也就是说,当模型对错本身不造成很大影响的时候,解释性并不算是很重要的要素。不过当预测模型用于金融、公共事务等重大影响决策时,解释性就显得尤为重要了。 可解释的机器学习 理解(interpret)表示用可被认知(understandable)的说法去解...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Mario游戏-低调大师作品
- 2048小游戏-低调大师作品
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Red5直播服务器,属于Java语言的直播服务器
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库