Bean注入几种方式 (放入Spring容器)
目录
1、XML方式注入
set方式注入
构造方法注入
2、注解方式注入
@Component + @ComponentScan
@Configuration + @Bean + @ComponentScan
@Import
3、实现ImportBeanDefinitionRegistrar接口
4、实现FactoryBean
5、实现BeanDefinitionRegistryPostProcessor
一、XML方式注入
在现在这个Springboot横行的年代,以XML来注入的方式可能已经不多见了,因为压根用不着,但毕竟是注入方式之一也得提一提,这种方式就是依赖于XML的解析来获取我们需要注入的Bean对象
常见的方式有:set方法注入、构造方法注入
这里举几个常见的例子:
1、set方式注入

测试:

2、构造方法注入

测试:

二、注解方式注入
1、@Component + @ComponentScan
我们开发中常用的 @Service 和 @Controller都是@Component下的注解,需要配合@ComponentScan注解才能被扫描到并放入IOC容器中
为什么平时却没用 @ComponentScan注解呢 ?
因为平时用的都是Springboot,Springboot启动类上的 @SpringbootApplication注解类下已经带有 @ComponentScan注解了,默认扫描启动类同级包下的 @Component
例子如下:
我们先准备一个获取IOC容器内bean 的工具类 SpringUtils:

测试要注入的Bean实体类:


可以看到报错了,压根找不到这个bean,因为我们上面说过了springboot默认扫描的是启动类同级下的路径,我们把启动类放到了独立的包下,所以扫描不到了,这时候我们要么在用@ComponentScan注解配置一次扫描路径,要么把启动类提出来,我这里演示前者
我们在启动类上加上@ComponentScan注解配置一次扫描路径,就可以看到注入成功啦

2、@Configuration + @Bean + @ComponentScan
@Configuration注解相信大家也都不陌生,这个注解同样要配合@ComponentScan使用,那到底和@Component有什么区别呢 ?
@Configuration注入的是CGlib代理类,@Component注入的是类本身
我们与@Component一样准备个@Configuration注入类:


可以看到Bean类的本质区别,难道为了这个就搞了@Configuration注解吗?当然不是,这个注解还可以配合@Bean注解一起使用,用来同时注入多个Bean


这样的@Bean可以在同一个类中注入多个,所以@Component更多的用来注入配置文件类,@Configuration 更多的用来注入多个实例类
3、@Import
这种方式一般用在第三方包的加载比较多,使用起来呢也简单需要注入哪个Bean,导入哪个Bean的class就可以了,例如:

这个注解使用得注意,一定要能被扫描到才行,可以直接放在启动类上,如果是普通需要配合@Component或者@Configuration来使用,因为此注解单独使用是不会被扫描到的,也就不会被加载了
在一个注解上导入多个Bean要写这么多可能不是很优雅,所以还可以配合ImportSelector接口使用:

4、实现 ImportBeanDefinitionRegistrar接口
看接口名称就知道了是不是有点像Bean的注册接口,需要配合@Import使用:

测试:

我们平时开发中常用的openfeign也是采用的这种方式:

5、实现FactoryBean
用这个得先搞清楚FactoryBean和BeanFactory的区别:
BeanFactory:IOC容器顶层接口,用来Bean容器管理
FactoryBean:是一个bean,是一个能产生bean的工厂,本身也会作为bean给容器管理,所以作为一个能产生Bean的工厂,我们可以自定义Bean(这也是最关键的点)
让我们来看看怎么用:

测试:
可以看到通过Class无论是工厂bean还是工厂生产的bean我们都可以获取,但是发现通过beanName获取bean的区别没有,我们通过工厂的beanName获取到的是实际生产的对象,
要获取真正的工厂需要在beanName前面加上&
为什么通过工厂的beanName获取到的是实际生产的对象 ?
其实从上述注入的过程中也能看到我们往容器中注入的其实是工厂Bean,并没有注入工厂生产的那个对象(可以打印容器所有的beanName验证),可以理解为在从容器中获取Bean的时候有判断是否实现了FactoryBean接口,实现了则会调用该bean的getObject()方法返回,所以此时会返回实际工厂生产的对象了

我们一样以openfeign框架举例:
此注入的feign接口实际注入的是FeignClientFactoryBean,所以在调用容器中feign接口bean对象的时候,实际执行的是FeignClientFactoryBean.getObject()方法

6、实现BeanDefinitionRegistryPostProcessor
这个接口继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor是BeanFactory的后置处理器,该接口多个了一个对BeanDefination处理的方法,可以在BeanFactory生成后对里面的BeanDefination做一次处理,所以当然可以注册BeanDefination,后续就创建Bean了
BeanDefinitionRegistryPostProcessor源代码如下:

怎么用呢?先直接上例子吧:

乍一看和ImportBeanDefinitionRegistrar类似,都是用了BeanDefinitionRegistry 来注册的,但ImportBeanDefinitionRegistrar是Spring的扩展点之一,提供给第三方对接使用的
BeanDefinitionRegistryPostProcessor这个源码就不追溯了,后面再说(还是提一下吧,容器初始化的时候有调用)

既然是BeanFactory后置处理器,所以它还可以修改BeanDefination里面保存的Bean信息:

结果如下:

Bean注入几种方式 (放入Spring容器)的更多相关文章
- Spring装配Bean的三种方式+导入和混合配置
目录 Spring IoC与bean 基于XML的显式装配 xml配置的基本结构 bean实例的三种创建方式 依赖注入的两种方式 构造器注入方式 setter方法注入方式 利用命名空间简化xml 基于 ...
- spring 注入bean的两种方式
我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...
- 7 -- Spring的基本用法 -- 7... 创建Bean的3种方式
7.7 创建Bean的3种方式 ① 调用构造器创建Bean. ② 调用静态工厂方法创建Bean. ③ 调用实例工厂方法创建Bean. 7.7.1 使用构造器创建Bean实例. 使用构造器来创建Bean ...
- Spring依赖注入三种方式详解
在讲解Spring依赖注入之前的准备工作: 下载包含Spring的工具jar包的压缩包 解压缩下载下来的Spring压缩包文件 解压缩之后我们会看到libs文件夹下有许多jar包,而我们只需要其中的c ...
- SpringJUnit4加载类目录下(src)和WEF-INF目录下的配置文件二--获取注入的bean的二种方式
前言: spring容器以xml的形式注入bean,然后可以在类中获取,获取的形式主要有二种:第一种最简单--采用@Resource 或@Autowired关键字在加载spring文件时将bean注入 ...
- Spring实战(三)Spring中装配Bean的三种方式---XML、JavaConfig、AutoWire
创建应用对象之间协作关系的行为称为装配(wiring),这也是依赖注入的本质. Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系,而开发者需要告诉Spring需要创建哪些 ...
- spring创建bean的三种方式
spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...
- Spring学习之实例化bean的三种方式
实例化bean的三种方式 构造器实例化bean Person.java public class Person { private String name; private Integer age; ...
- 一篇关于spring ioc 依赖注入3种方式的文章引用
今天看到一篇spring ioc 容器依赖注入3种方式的文章,为了方便后面的复习,在此引用别人的文章,查看请戳我.
- 装配Bean的三种方式
一.装配Bean就是在xml写一个Bean标签:装配完Bean,还需要读取xml配置文件创建Spring容器来创建对象: 1.new 实现类方式 正常的三种创建Bean容器的方法都可以根据装配的Bea ...
随机推荐
- 第3章 在C#中创建类型
第3章 在C#中创建类型 3.1 类 复杂的类可能包含如下内容: 在 class 关键字之前:类特性(Attribute)和类修饰符.非嵌套的类修饰符有:public.internal.abs ...
- verilog 编写猫狗过河实验
源代码地址:https://github.com/penggeon/catanddog 效果演示见: https://www.bilibili.com/video/BV1n24y147S1 警告: 仅 ...
- 一个基于 C# 开源的第三方 OAuth2 授权登录整合库
前言 在我们的开发工作中有可能会对接过各种各样的第三方平台的登录授权,来获取用户的相关账号信息(如:微信登录.支付宝登录.飞书登录.钉钉登录.GitHub登录等等).今天大姚给大家推荐一个基于 C# ...
- C# Winform 实现静态变量属性的值变了,触发事件,类似WPF的双向绑定
在C# WinForms中,虽然没有像WPF那样内置的双向绑定机制,但你可以通过事件和属性封装来实现类似的功能.具体来说,你可以在静态属性的set访问器中触发一个自定义事件,然后在需要的地方订阅这个事 ...
- SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
在SQL Server数据库中,统计信息更新(UPDATE STATISTICS)会被其它会话阻塞吗?统计信息更新(UPDATE STATISTICS)会引起其它会话阻塞吗?在回答这两个问题前,我们必 ...
- oracle 删除过期归档脚本
一.定时任务 crontab -e 编辑 每周6凌晨3点执行脚本 0 3 * * 6 . /home/oracle/scripts/arch_delete_before_60days_arch.sh ...
- 你还不会使用Pycham Remote development 打开远程主机工作目录吗?这篇文章帮你解决!
前言 必备: 本地开发机与远程主机都要安装Pycharm专业版!!! 废话不多说直接开始!! 1.打开pycharm 2.依次点击File.Remote Development 3.依次点击SSH.N ...
- 反范式设计,冗余用户姓名,修改用户姓名后,业务表同步更新 -- MySQL 存储过程
反范式设计,冗余用户姓名,通过存储过程进行业务表的同步更新. 所有的表,在创建的时候,都加了创建人.修改人的字段..用户姓名发生变化时,要将所有的表都更新一遍. 创建存储过程 MySQL CREATE ...
- layui 自动触发radio和select
layui对radio和select做了包装,正常用jquery选中后使用trigger不起作用. 那么,怎么让其自动触发呢? 对radio来说,必须在$选中后.next('.layui-form-r ...
- 三分钟掌握音视频处理 | 在 Rust 中优雅地使用 FFmpeg
前言 音视频处理看似高深莫测,但在开发中,我们或多或少都会遇到相关需求,比如视频格式转换.剪辑.添加水印.音频提取等. FFmpeg 作为行业标准,几乎无所不能,很多流行的软件(如 VLC.YouTu ...