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 ...
随机推荐
- 手撸原生js放大镜效果
普及知识:放大镜特效涉及到的几个值 offsetWidth 获取元素的宽度offsetHeight 获取元素的高度offsetLeft父元素没有定位时,获取元素距离页面的左边距,父元素有定位时 ...
- 第一个helloworld,有点小兴奋
@SpringBootApplication package com.ch.boot; import org.springframework.boot.SpringApplication; imp ...
- 9. SpringCloud Alibaba Sentinel 流量控制、熔断降级、系统负载,热点规则的部署设置讲解
9. SpringCloud Alibaba Sentinel 流量控制.熔断降级.系统负载,热点规则的部署设置讲解 @ 目录 9. SpringCloud Alibaba Sentinel 流量控制 ...
- Mac安装Prometheus + Grafana
一.安装Prometheus 1.下载安装 brew install prometheus 2.安装路径 /opt/homebrew/Cellar/prometheus/3.1.0 3.修改配置文件 ...
- QT5笔记: 23. 标准对话框
文件对话框: QString fileName = QFileDialog::getOpenFileName(this, "打开一个文件", path, "文本(*.tx ...
- DataX - [02] 安装部署
操作系统:Alibaba Cloud Linux release 3 (Soaring Falcon) Java:1.8.0_372 Python:3.6.8 => 2.7.1 一.安装部署 ( ...
- 基于RAG的MaxKB知识库问答系统如何选择向量模型
在MaxKB中替换向量模型前,我们需要先了解向量相关的原理和技术,此处不做赘述,大家可以自行学习.可以了解下Embedding.Embedding核心,向量库等内容. 一.MaxKB 默认向量模型 M ...
- python面向对象-我敢站在世界巅峰保证:这里可以找到几乎百分之九十python面向对象的内容(面向对象三大特性、成员、组合、特殊成员、反射、类的约束、自定义异常、多继承之C3算法)
概要: 面向对象 2 面向对象 Java语言:只支持面向对象方式 python语言: 面向过程[不推荐] 函数式[推荐] 面向对象[比较推荐]了解.能看懂.看源码 函数式编程:代码重用性.可读性较好 ...
- wordpress无法显示gitee图床的图片
wordpress无法显示gitee图床的图片 Question:如题 Solution:是防盗链的问题,gitee官网给出了防盗链的方法,而github貌似没有. Reference:你已经是个成熟 ...
- rust学习笔记(7)
crate 中文是货箱,这是我们编写自己的库或者程序的方式 库 使用rustc可以把一个文件编译为lib rustc --crate-type=lib rary.rs 构建的方式选择lib 编译出来的 ...