确定不了解一下Spring两大核心之一的IOC容器嘛

今天菜鸟和大家一起来探讨一下Spring两大核心之一的“IOC” 。
IOC是什么IOC是“Inversion of Control”的缩写,翻译过来就是“控制反转” 。
我们先不深究其在Spring中的含义,先从字面上进行分析 。打个比方来说:结婚前你的工资完全由你来支配,想怎么花就怎么花 。结婚后变了,你的钱要上交给你媳妇了,你想花的时候得申请 。此时你对工资的控制转变了,由原来的你控制,变成了你媳妇控制 。这就是“控制反转”,本来属于你控制的事情,交由别人来控制,而你只在需要的时候进行获取就可以了 。
相信通过这个比喻大家对“控制反转”的含义都已经理解了,那么它在Spring中的体现就是:把创建对象的过程交给Spring来进行管理,从而做到将原来需要自己手动new对象,变成直接从Spring中获取 。
这就就好比Spring中有一个容器,我们将Bean放到这个容器中,让这个容器为我们创建实例,当需要时我们直接从这个容器中进行获取即可 。这个容器的实现理念就是IOC 。

确定不了解一下Spring两大核心之一的IOC容器嘛

文章插图
 
为什么使用IOC使用IOC最大的好处就是减少了代码的耦合度,降低了程序的维护成本 。
可能很多人都知道这个道理,就是不太明白它到底是怎么降低的,别慌下面让我来给大家讲解一下 。
假设现在有一道菜:宫保鸡丁 。
// 伪代码public class KungPaoChicken {public static KungPaoChicken getKungPaoChicken(各种食材) {// 加工各种食材最终得到一份美味的宫爆鸡丁 。return KungPaoChicken;}}传统做法
如果现在不使用IOC,我们想要吃到宫保鸡丁,那么就需要如下操作 。
// 伪代码public class Person() {// 采购各种食材// 准备好各种食材通过KungPaoChicken获取到一份宫保鸡丁 。KungPaoChicken kungPaoChicken = KungPaoChicken.getKungPaoChicken(各种食材);}代码之间的耦合关系图:
确定不了解一下Spring两大核心之一的IOC容器嘛

文章插图
 
看起来也不难,也不麻烦对吧?
别着急下定论,现在只是一个人想要宫保鸡丁,假如现在有10个人都想要那?是不是有十份相同的代码?这10个人都和KungPaoChicken有耦合 。又比如现在需要的食材有所改变,那这样的话是不是这10个人都需要调整代码?这么一来是不是发现这种实现方式一点也不友好 。
使用IOC的做法
现在我们转变一下思路,不再自己动手做了,我们把这道菜的做法告诉饭店,让饭店来做 。
// 伪代码public class Restaurant {public static KungPaoChicken getKungPaoChicken() {// 处理食材,返回宫保鸡丁retur KungPaoChicken;}}转变之后的耦合关系图:
确定不了解一下Spring两大核心之一的IOC容器嘛

文章插图
 
经过这样处理,就可以很大程度上解决上面的这些问题 。
1、我们将KungPaoChicken交给Restaurant(饭店)来进行管理,它的创建由Restaurant进行 。
2、现在不论是1个人还是10个人我们只需要从Restaurant中进行获取就可以了 。这样耦合就改变了,Person只需要和Restaurant发生耦合就可以了 。
3、当KungPaoChicken有变动时,也不需要每个人都变动,只需要Restaurant随之改变就可以了 。
Spring的IOC容器就充当了上面案例中的Restaurant角色,我们只需要告诉Spring哪些Bean需要Spring进行管理,然后通过指定的方式从IOC容器中获取即可 。
Spring提供的IOC容器Spring提供了一个接口BeanFactory 。这个接口是Spring实现IOC容器的顶级接口,这个接口是Spring内部使用的,并不是专门为框架的使用者提供的 。
确定不了解一下Spring两大核心之一的IOC容器嘛

文章插图
 
我们一般使用的是BeanFactory的子接口ApplicationContext接口,这个接口提供了更多并且更加强大的功能 。
在ApplicationContext接口中有三个常用的实现类分别是:AnnotationConfigApplicationContext、FileSystemXmlApplicationContext、ClassPathXmlApplicationContext 。
容器的创建需要读取配置文件或配置类,通过这些配置告诉Spring哪些bean是需要Spring来进行管理的 。
注意:读取配置文件时,如果读取绝对路径时入参需要添加前缀“file:”,读取相对路径时入参需要添加“classpath:” 。
AnnotationConfigApplicationContext
作用:用于在全注解开发时,读取配置类的相关配置信息 。
注意:通过@Configuration注解标注当前类为Spring的配置类


推荐阅读