Spring01——SpringIoC容器

  1. 云栖社区>
  2. 博客>
  3. 正文

Spring01——SpringIoC容器

小江同志 2018-09-30 11:31:00 浏览515
展开阅读全文

一、spring概述

spring出现于2004年,其最早是由澳大利亚的音乐专家所提倡的,主要是由于EJB时代,EJB2需要许多配置文件和配合很多抽象概念才能运用,而EJB3虽然克服了配置方面的冗余,但致命的是对EJB容器的过分依赖,也就是EJB只能运行在EJB容器中,EJB容器又显得笨重,EJB应用难以达到快速开发和测试的目的。而在spring中,一切Java类都是资源,资源也就是bean,容纳这些bean的是spring提供的IoC容器,spring就是一种基于bean的编程,主要是配置bean。spring技术不是为了取代所有技术,而是提供更好的整合模板使他们能够整合到spring技术上来。而spring框架也是无侵入性或者地侵入性的(即即使Java应用离开了spring依旧可以运用),拥有即拔即插的功能。

二、springIoC阐述

IoC(控制反转)是一个比较抽象的概念,我举个例子,比如你现在要吃蛋炒饭,你除了得准备蛋和饭等等还必须会自己炒,这就是你对需要的东西的主动创建,而控制反转则反过来了,它可以看成是被动创建的过程,比如同样你是要吃蛋炒饭,你可以直接打开美团外卖里的商家通过你的描述点餐,然后它送到你的地址给你,这样你无须知道怎么蛋炒饭怎么制作的,但你一样吃到了蛋炒饭,全程你也不需要知道蛋炒饭的制作流程。或者在团队中,你可能熟悉商品的交易流程,对财务你不怎么熟悉,而团队其他人熟悉,这么一来,可以由熟悉财务流程的成员开发对应的接口,接口逻辑尽量简单,内容多复杂你也不需要管,你只要通过简单地描述调用接口就能使用了。这里可做类比:蛋炒饭就相当于财务接口,而美团外卖里的商家就相当于熟悉财务流程的同事,你对蛋炒饭的描述和地址就等同于获取财务接口实例的描述。当我们对某一领域不精通,这个时候我们可以把创建对象的主动权转交给别人,这就是控制反转的概念。

控制反转是一种通过描述(在Java中可以是XML或者注解)并通过第三方去产生或获取特定对象的方式。比如上方我们只需要知道美团外卖可以点我想要的蛋炒饭,而不需要去理解怎么创建蛋炒饭的。它最大的好处在于降低了对象之间的耦合。主动创建模式下,责任归于开发者,被动创建模式下,责任归于springIoC容器。springIoC容器的主要2功能是:①容纳bean;②提供bean。

springIoC容器的设计是基于BeanFactory和ApplicationContext两个接口,其中BeanFactory是springIoC容器所定义的最底层接口。大多数场景下,都会使用ApplicationContext作为springIoC容器。

BeanFactory接口源码分析:

getBean()的多个方法用于获取配置给springIoC容器的Bean;

isSingleton()用于判断是否单例,若为true则该bean是容器的唯一单例;

isPrototype()则相反,即为false时,你从容器中获取bean,容器会为你生成一个新的实例;

img_39fb8835400bed4afa4a0b5230a2a16a.png

用代码举个例子:

先创建一个实体POJO类

img_60dd5f8df504892b309df6706757a8f0.png
POJO类

再创建一个果汁制作者类

img_2b76df6bbfb46d633f292fc00fdf2b9b.png
makeJuice

创建spring-cfg配置文件管理bean

img_cf47611a6d32135acc1e140b66ff031c.png

最后写个测试类调用

img_40b65e28bdbac86d6a2f22ba1a5c2401.png

运行效果:

img_33b4cd043d38f3109c45d55e30b951d3.png

就这样,通过spring配置我们很灵活的就完成对象的创建使用而不是通过new对象的方式来实现,实现了解耦合的效果。

三、springIoC容器的初始化和依赖注入

注意,bean的定义和初始化在springIoC容器中是两大步骤,先定义,然后才初始化和依赖注入的。

bean定义分三步:

①Resource定位:在spring的开发中,通过XML或者注解都是常见的方式,定位的内容是由开发者所提供的。

②BeanDefinition的载入:这时候只是将Resource定位到的信息,保存到BeanDefinition中,并不会创建bean实例。

③BeanDefinition的注册:这个过程就是将BeanDefinition的信息发布到springIoC容器中,注意此时仍然没有对应的bean实例创建。

做完以上三步bean就在springIoC容器定义了,但没有被初始化,更没有依赖注入,也就没有诸如其配置的资源给bean,它还不能完全使用。当我们使用springIoC容器的getBean()方法获取它时,它才会进行bean的初始化,完成依赖注入。springIoC容器的本质目的就是为了管理bean。

了解bean的生命周期,以便我们可以在springIoC容器初始化和销毁bean时加入自己的自定义方法,以满足特定的需求。

img_ca73098c8a0a71b4ab109e1cfb06bb54.jpe
bean的生命周期过程

注意:上述的bean大部分是针对单个bean而言,而BeanPostProcesser接口是针对所有bean而言的。
用代码举个测试说明(基于上面的juiceMaker代码基础添加代码):

img_9a4ffe4b9dfb62afe962b9ef5139cd2b.png
修改配置文件
img_37f74371f1ec21120d54d724b175117a.png
程序打印日志

根据程序打印日志结果出来看,我们可以对bean生命周期函数执行顺序排序

img_08bde0e84011a8d619ba0cecb266ba2c.png
img_f553f1dceaa3ca55ecabf5a0956a3ed6.png

以上就是执行的顺序了。可以看到BeanPostProcessor针对全部bean

网友评论

登录后评论
0/500
评论
小江同志
+ 关注