1 概念
IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。
1.1 什么是IOC(Inversion of Control)
传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
传统程序设计下,都是主动去创建相关对象然后再组合起来:
![图片[1]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-105-1024x338.png)
当有了IOC容器后,在客户端类中不再主动去创建这些对象了,如图:
![图片[2]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-106-1024x433.png)
1.2 什么是DI(Dependency Injection)
DI是IOC的实现。由于控制反转概念比较含糊,所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IOC 而言,“依赖注入”明确描述了“被注入对象依赖IOC容器配置依赖对象”。
通俗来说就是IOC是设计思想,DI是实现方式。
2 IOC原理
2.1 底层原理
xml 解析、工厂模式、反射
2.2 IOC 容器
- IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂
- Spring 提供 IOC 容器实现两种方式:(两个接口)
- BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用。加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象
- ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用。 加载配置文件时候就会把在配置文件对象进行创建
3 Bean管理
- Bean 管理指的是两个操作
- Spring 创建对象
- Spirng 注入属性
3.1 基于 xml 配置方式
3.1.1 创建对象
在 spring 配置文件中,使用 bean 标签,标签里面添加对应属性,就可以实现对象创建。
![图片[3]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/127c29e82be3b6ce6050ba7d429f5c4.png)
创建对象时候,默认是执行无参数构造方法完成对象创建。我们不写无参构造看下效果:
![图片[4]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-108.png)
![图片[5]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-109-1024x343.png)
3.1.2 注入属性
1. set注入
![图片[6]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-110.png)
![图片[7]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-111.png)
运行代码可以看到属性注入成功:
![图片[8]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-112.png)
2. 有参数构造注入
![图片[9]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-113.png)
![图片[10]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-114.png)
演示结果:
![图片[11]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-115.png)
3.1.3 其他类型注入演示
1. null
![图片[12]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-116.png)
2. 外部Bean
![图片[13]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-118.png)
![图片[14]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-117.png)
3. 注入集合
![图片[15]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-119.png)
![图片[16]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/10/image-120.png)
3.1.4 FactoryBean
- Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)
- 普通 bean:在配置文件中定义 bean 类型就是返回类型
- 工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样
- 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
- 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
![图片[17]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image.png)
![图片[18]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-1.png)
![图片[19]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-2-1024x462.png)
3.1.5 bean 作用域
1 单例
在 Spring 里面,默认情况下,bean 是单实例对象
![图片[20]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-3-1024x466.png)
2 多例
- 在 spring 配置文件 bean 标签里面有scope属性用于设置单实例还是多实例
- 默认值,singleton,表示是单实例对象
- prototype,表示是多实例对象
![图片[21]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-4.png)
![图片[22]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-5-1024x473.png)
3 singleton 和 prototype 区别
- 设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象
- 设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用getBean 方法时候创建多实例对象
3.1.6 xml 自动装配
在 spring 配置文件 bean 标签里面有autowire属性用于配置自动装配,根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入。
- byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
- byType 根据属性类型注入
1 根据属性名称自动注入
![图片[23]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-6.png)
![图片[24]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-7-1024x434.png)
2 根据属性类型自动注入
![图片[25]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-8.png)
![图片[24]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-7-1024x434.png)
3.2 注解方式
Spring 针对 Bean 管理中创建对象提供注解
- @Component
- @Service
- @Controller
- @Repository
3.2.1 注解方式创建对象
第一步 引入依赖
![图片[27]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-9.png)
第二步 开启组件扫描
![图片[28]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-11.png)
第三步 创建类,在类上面添加创建对象注解
![图片[29]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-10.png)
3.2.2 注解方式实现属性注入
1 @Autowired
根据属性类型进行自动装配
![图片[30]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-12.png)
2 @Qualifier
根据名称进行注入,和上面@Autowired 一起使用
![图片[31]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-13.png)
3 @Resource
可以根据类型注入,可以根据名称注入
![图片[32]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-14.png)
4 @Value
注入普通类型属性
![图片[33]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-15.png)
3.2.3 完全注解开发
创建配置类,替代 xml 配置文件
![图片[34]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-16.png)
扫描配置类
![图片[35]-Spring IOC-深吸氧](https://xiyang-blog.oss-cn-hangzhou.aliyuncs.com/blog/2022/11/image-17-1024x198.png)
暂无评论内容