一篇解决Spring IOC问题

758 阅读6分钟

干货有质量,水文有情怀,微信搜索【程序控】,关注这个有趣的灵魂

前言

Sprig家族的东西太多,一次性写完也不现实,我们先从最基本的,也是最重要的开始学起:IOC和AOP(本篇IOC,下一篇AOP)

无论是入门还是面试,理解AOP和IOC都是非常重要的。在面试的时候,像Mybatis/Hibernate/Struts2这样的框架,问的相对比较少,而Spring就经常会被问到。

在这里插入图片描述

IOC和DI概述

IoC(Inversion of Control)控制反转,是将类对象的创建交给Spring管理。 DI(Dependency Injection)依赖注入,是在DI的基础上完成。

我们可以简单的认为:

  • IOC类似一个工厂,即拥有创建类对象的权利,我们不用每次去new对象了。
  • DI就是对某一接口实现类的依赖关系由第三方注入,以移除调用类对某一接口实现类的依赖

我们现在就可以很清楚的发现,其实所谓的IOC容器就是一个大工厂【第三方容器】。

我们写代码,不仅仅是要能实现功能,实现完了以后我们还得对写过的代码「维护」。如果我们的代码写得很烂,那维护的成本就很高。

面对重复的/繁琐的非业务代码:

  1. 如果程序有问题,我们需要看代码,找问题
  2. 如果想要在原有功能上加一个新功能,我们需要修改原有的代码,较麻烦...(AOP解决)

我们使用ORM框架,那么我们就可以更加「专注」去实现本身的业务,ORM框架把「重复」的代码都屏蔽掉,代码维护起来就比JDBC要方便。 在这里插入图片描述 Spring IOC 解决的就是 对象管理和对象依赖的问题。本来我们的对象都是new出来的,而我们如果使用Spring 则把对象交给「IOC容器」来管理。

IOC容器:可以理解为是一个「工厂」,我们把对象都交给这个工厂来管理,包括对象的创建和对象之间的依赖关系等等。当我们要用到对象的时候,就从这个「工厂」里边取出来。

控制反转:本来是由我们自己new出来的对象,现在交给了IOC容器。把这个对象的「控制权」给他方了。「控制反转」更多的是一种思想或者说是设计模式,把原有由自己掌控的事交给「别人」来处理。

依赖注入:指的是「控制反转」这个思想的实现方式,对象无需自行创建或管理它们的依赖关系,依赖关系将被「自动注入」到需要它们的对象当中去。

个人对这些名词是不太敏感的,我觉得吧没必要太纠结很多名词的概念,理解其内部含义即可。

IOC使用

我们在使用Spring IOC的时候,首先需要学习的是如何把对象交给IOC容器来管理对象,由容器来创建。

Spring提供了四种方式

  • 注解
  • XML
  • JavaConfig
  • 基于Groovy DSL配置

总的来说:我们以XML配置+注解来装配Bean,获取对象比较多,其中注解这种方式占大部分。

当我们把对象放到IOC容器中的时候,对象之间的依赖关系需要我们来告诉Spring,这样它才可以帮助我们解决掉对象的依赖关系。

对象之间的关系」别想得太复杂了,在日常开发中其实很多时候就是A对象里边有B对象的属性而已。 在这里插入图片描述 一般来说我们会通过 构造器或者属性(setting方法) 的方式来注入对象的依赖

举个例子: 日常开发中,我们很多时候用@Component注解标识将对象放到「IOC容器」中,用@Autowired注解将对象注入

下面这张图就很好总结了以各种方式来对Bean的定义和注入。 在这里插入图片描述

IOC容器装配Bean

从上面就已经说了:IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系。

依赖注入的方式有3种方式:

  • 属性注入-->通过setter()方法注入
  • 注解注入-->@Autowired这些
  • 构造函数注入

我遇到的情况一般都是注解注入和属性注入,一般注解注入稍微多一些

Bean的五种作用域:

  • 单例Singleton
  • 多例prototype
  • 与Web应用环境相关的Bean作用域
  • reqeust
  • session

在web中Bean作用域的话,需要我们手动配置代理的~ 在这里插入图片描述

了解Bean

Spring中的lazy-init(延迟加载)默认是false,也就是默认是非延迟加载,一旦容器初始化,会加载所有的Bean对象进行初始化,通常情况下这是一件好事,因为在配置中的错误(对象创建失败、依赖问题等)会立马出现。

创建Bean对象的时机:

  • 非延迟加载下,容器初始化时创建所有Bean对象;
  • 延迟加载下,调用getBean获取对象实例时创建对象;
  • 延迟加载下,作为其它对象的依赖创建(A依赖于B,获取A对象时创建B对象);

我们上面说到了非延迟加载的优点是可以检查错误,同时它也是有缺点的~~

  • 占用内存空间大,因为创建了很多暂时用不到的对象;
  • 服务启动时间慢,也是因为创建对象多了;

简单了解一下Bean的实例化过程:

在这里插入图片描述 Bean的生命周期:

  1. 创建bean对象
  2. 设置bean属性和初始化
  3. 使用bean
  4. 执行销毁方法

絮叨

你知道的越多,你不知道的也越多。

建议:多读书,多看视频,少吃零食,多撸代码

重要的一点千万就是不要被「名词」给吓唬了,名词太多太多了,如果没听过的名词可能会认为很厉害,其实等真正接触下来,学习完了以后,发现也不过如此嘛。 在这里插入图片描述

觉得不错的可以关注我的微信公众号【程序控】,湿兄会一直坚持给大家分享技术文章,让大家悄悄拔尖,然后惊艳所有人~~

在这里插入图片描述