Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官!

前一篇《不要再说不会Spring了!Spring第一天,学会进大厂!》文章可点击下方链接进行回看。
不要再说不会Spring了!Spring第一天,学会进大厂!
今天将继续讲解Spring的注册bean的方式。将通过代码片段+源码的方式,用图文结合来讲清楚这些注册bean的方式。
一、@Conditional条件注册bean
@Conditional:是Spring4新提供的注解,它的作用是按照一定条件进行判断,满足条件后往IOC容器中进行注册。
场景:往IOC容器中注册bean时,当操作系统为Windows时,注册cansluck实例;当操作系统为Linux时,注册xgx实例;此时用到@Conditional注解进行定制化条件选择注册bean。
实例:

新建WinCondition.java类作为条件类,用来处理操作系统为Windows的bean注册;同时必须得实现Spring提供的Condition接口。
WinCondition.java类:

新建LinuxConditional条件类,用来处理操作系统为Linux的bean注册。
LinuxConditional.java类:

来解析一下接口Condition,看下Condition接口的代码(JDK封装):

接口中定义了一个抽象方法:matches(),返回true时,则意味着注册被注解的bean,反之返回false。因此实现该接口时,都要实现该接口的matches抽象方法。
ConditionContext接口为获取IOC容器或者对象工厂的接口,里面提供了几个抽象方法,如下图:

可以看到提供了5个抽象方法,分别返回不同的对象。在这里我们用到getEnvironment()获取到当前编译环境的方法,来结合场景配合@Conditional注解来使用。(有兴趣的朋友可以自行拓展,比如获取IOC容器bean可以使用getBeanFacroty()方法等等。)
回过头来,我们在MainConfig.java配置类中,如果为windows环境,则将cansluck注册到IOC容器中;如果为linux环境,则将xgx注册到IOC容器中。下面用测试类来测试一下:

我们可以看到person是传统@Bean注解进行了注册,当前环境为windows环境,因此cansluck符合条件,因此将cansluck注册到IOC容器中,xgx并没有注册到IOC容器。
如果不加@Conditional注解,则会将cansluck和xgx全部注册到IOC容器中(这里就不做演示了,有兴趣的小伙伴可以自行去掉注解进行操作);因此当引入@Conditional注解时,容器可以选择性注册bean。
二、@Import注册bean
上面讲的基本上是@Bean的方式往IOC容器中注册bean,那样需要在配置类中添加多个对应bean的实现方法,这样也会让代码看起来非常的冗余。因此Spring也提供了@Import注解的方式,可以按照数组的形式,添加一个或者多个bean完成IOC容器中bean的注册。
1. 使用@Import注解方式注册bean
当前项目中,已经建立了一个Person实体类,并且通过@Bean的方式往IOC容器中注册bean。
现在,分别再建立一个Dog 和 Cat 实体类,通过@Import的方式往IOC容器中注册备案。
代码如下:
新建Dog.java 和 Cat.java 类


MainConfig.java配置类

这样,就能够不需要再写@Bean的方式写很多方法,而是可以通过@Import注解的方式,将一个或者多个类注册往IOC容器中进行注册。就省了很多重复代码工作量的过程。
2. 使用@ImportSelector注册bean
使用@ImportSelector注解可以批量导入组件的全类名数组,自定义逻辑返回需要导入组件对应ImportSelector.java类
代码如下:
新建Fish.java 和 Tiger.java类


CansluckImportSelector.java类

MainConfig.java配置类

Test测试类

通过测试类测试后可以看到,Fish和Tiger两个实体类也被注册到了IOC容器中。
3. 使用@ImportBeanDefinitionRegister注册bean
使用@ImportBeanDefinitionRegister自定义注册向IOC容器注册bean。
新建Pig.java类

CansluckImportBeanDefinitionRegistrar.java类

(在上面的代码中,我们看到引用了RootBeanDefinition类对象进行实例化,在后续的持续学习中,会介绍到该类的一个源码介绍,而且会发现基本上都是用了这个类来进行bean的注册)
MainConfig.java配置类

Test测试类

通过测试类测试后可以看到,Pig实体类也被注册到了IOC容器中。
4. 通过实现FactoryBean接口来注册bean
新建Monkey.java类

CansluckFactoryBean.java类

可以看到实现了FactoryBean接口,并实现了三个抽象方法。
可以先来看下FactoryBean的源码:


使用Spring提供的FactoryBean(工厂bean)接口,可以根据源码看到有三个抽象方法:
1. getObject()返回对象,把对象放到容器中;
2. getObjectType()返回对象类型;
3. isSingleton()是否单例进行控制
MainConfig.java配置类

在这里采用了@Bean的方式进行注册,也可以在@Import中引入进行注册
以上就是给容器注册组件的方式。有兴趣的小伙伴可以根据案例自行尝试并阅读源码进行分析。
给容器中注册组件的方式总结
1. @Bean:【导入第三方的类或包的组件】
2. 包扫描 + 组件的标注注解(@ComponentScan: 针对@Controller、@Service、@Reponsitory、@Component),一般是针对我们自己写的类使用该方式
3. @Import:【快速给容器导入一个或多个组件】,@Bean有点简单
① @Import(要导入到容器中的组件):容器会自动注册这个组件,其中注册的bean的id为组件的全路径类名(比如com.java.xxx.Person)
② ImportSelector:是一个接口,返回需要导入到容器的组件全类名数组
③ ImportBeanDefinitionRegistrar:可以手动添加组件到IOC容器中,所有Bean的注册可以使用BeanDefinitionRegistry(例如写CansluckBeanDefinitionRegistrar实现ImportBeanDefinitionRegistrar接口即可)
④ 使用Spring提供的FactoryBean(工厂Bean)进行注册
以上为Spring相关给容器中注册组件的方式总结,小伙伴们有更多的一些建议和看法可以在下方进行留言。
码字不易,希望能够点赞,关注,分享~谢谢啦
< END >

Java极客思维
微信扫一扫,关注公众号
Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官!的更多相关文章
- spring给容器注册组件 的几种方式
环境搭建: 新建一个maven项目,引入依赖 <dependency> <groupId>org.springframework</groupId> <art ...
- spring 给容器中注册组件的几种方式
1.@Bean 导入第三方的类或包的组件 2.包扫描+组件的标注注解(@ComponentScan: @Controller,@service,@Reponsitory,@Componet), 自己写 ...
- JDBC注册驱动的三种方式
JDBC注册驱动的三种方式 1.通过导入的JDBC的驱动包拿到的com.mysql.jdbc.Driver对象,利用java.sql.DriverManager对象的DriverManager.reg ...
- Spring事务失效的 8 大原因,这次可以吊打面试官了!
今天再来一篇<吊打面试官>系列,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新--) 前几天栈长不是发了一篇文章,里面有一个关于事务失效的问题: 用 Spring ...
- jQuery---on注册事件的2种方式
on注册事件的2种方式 on注册事件的语法 on注册简单事件 // 这个是p自己注册的事件(简单事件) $("p").on("click", function ...
- Spring为IOC容器注入Bean的五种方式
一 @Import导入组件,id默认是组件的全类名 //类中组件统一设置.满足当前条件,这个类中配置的所有bean注册才能生效: @Conditional({WindowsCondition.clas ...
- 【Spring】Spring之向 IOC 容器注入对象的三种方式
关于Spring的搭建可参见:浅析Spring框架的搭建.在测试之前还是应该先将环境配置好,将相关Jar包导进来.Spring创建的对象,默认情况下都是单例模式,除非通过scope指定. 向IOC容器 ...
- Spring Boot2 系列教程(十五)定义系统启动任务的两种方式
在 Servlet/Jsp 项目中,如果涉及到系统任务,例如在项目启动阶段要做一些数据初始化操作,这些操作有一个共同的特点,只在项目启动时进行,以后都不再执行,这里,容易想到web基础中的三大组件( ...
- Spring总结——控制反转,注入(配置和注解两种方式)
一.Spring的容器: 1.什么是控制反转:传统的方法,当某个java对象A需要调用对象B时,是由调用者(对象A)通过new关键字来创建对象B的(也可以说类A依赖类B),而在Spring中,则是由s ...
随机推荐
- 赋予楼宇“智慧大脑”:厦门双子塔3D可视化
前言 今年10月7日,是国务院批准设立厦门经济特区40周年纪念日.1980年的这一天,国务院正式批复同意在厦门湖里地区划出一块2.5平方公里的土地,设立经济特区.厦门,成为中国最早设立的四个经济特区之 ...
- CentOS8 yum安装Mariadb10.4
CentOS8 yum安装Mariadb10.4 https://downloads.mariadb.org/mariadb/repositories/#distro=CentOS&distr ...
- Win10中装Win10---virtualbox虚拟机的安装及拓展
最近在准备一档专栏时,发现我电脑中已经把一些环境配置完了,卸掉重装又显得麻烦,于是我就求助于虚拟机,虚拟机确实是个很好的东西,不久前我的一个伙伴向我请教虚拟机怎么装,发现这玩意三言两语还很难说清,于是 ...
- C++实现求离散数学命题公式的真值表
一.实验内容 (1)求任意一个命题公式的真值表. (2)利用真值表求任意一个命题公式的主范式. (3)利用真值表进行逻辑推理. 注:(2)和(3)可在(1)的基础上完成. 二.实验目的 真值表是命题逻 ...
- 51node1256 乘法匿元(扩展欧几里得)
#include<iostream> using namespace std; int gcd(int a,int b,int &x,int &y){ if (b==0){ ...
- HEAP CORRUPTION DETECTED:after Normal block错误方法解决
一:问题描述: 出现的问题如下: 二:问题产生的原因说明 该问题发生于操作堆内存的时候.产生该问题的原因是:你实际使用的内存大小超出了你实际申请的内存大小,在释放内存的时候就会发生该问题. 举个例子: ...
- uniapp使用swiper组件做tab切换动态获取高度
swiper对高度进行了限制,所以说通常做出了tab切换的效果但是内容经常被截取掉???? 所以我在前端做了一个动态获取高度的功能 选项卡标题也就是tab切换的效果 选项卡内容区域的高度自适应 因为进 ...
- ES & Filebeat 使用 Pipeline 处理日志中的 @timestamp
使用 Pipeline 处理日志中的 @timestamp Filebeat 收集的日志发送到 ElasticSearch 后,会默认添加一个 @timestamp 字段作为时间戳用于检索,而日志中的 ...
- linux上性能调优常用命令及简介
1.综合命令:nmon.top:topas(aix) d :磁盘相关 c:cpu相关 m:内存相关 2.磁盘 2.1 测试顺序写性能dd if=/dev/zero of=/cdr/test.data ...
- 【QT】QThread源码浅析
本章会挑出QThread源码中部分重点代码来说明QThread启动到结束的过程是怎么调度的.其次因为到了Qt4.4版本,Qt的多线程就有所变化,所以本章会以Qt4.0.1和Qt5.6.2版本的源码来进 ...