IOC(控制反转): 传统javaSE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象,而Ioc是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建。
大家都知道spring的核心组件分别是IOC和AOP等,其中IOC是目前开发中用的最多也最熟悉的,那么spring是怎么实现IOC组件功能的呢?我们先从IOC容器的结构出发深入浅出的讲解Spring的IOC组件,由于Spring中的IOC功能实属很强大, 我会将这个作为一个系列去讲解Spring的IOC功能,当然,本人对SpringIOC功能也不是全知全会,只是将自己的一些浅薄的见解通过文章表现出来,如果有什么理解不对的地方,希望各位能在评论或者私信我。
springIOC容器的启动过程如下:
这个过程就是对Spring源码IOC容器初始化的一个抽象理解,如果是不太清楚SpringIOC容器的源码的小伙伴可能会很陌生,对于这种对有看过spring源码的小伙伴,这里只需要你们有个粗略的印象就好,后面我会通过一个专栏去讲解这个SpringIOC容器的启动过程和Bean的创建过程,所以不要着急,先有个大概的印象,对之后我们去跑源码的时候会很有帮助。
上面,我们已经对SpringIOC容器组件进行了一个粗略的了解,下面我们再对SpringIOC容器的各个组件的继承关系、具体功能做一个解释:
是Spring对资源描述的组件,是信息的一个载体,像各种类型的文件、二进制流都是资源,这里大家应该也能想到,Spring使用过程中会使用很多资源,如xml、properties等,而Resource就是这些文件的一个载体,这个组件中有两个常用的类,如FileSystemResource表示文件系统上的资源,UrlResource则是表示网络资源。
从Resource接口的继承关系,我们也能清楚的知道它就是对文件资源的一种描述。Resource的类图中的ServletContextResource故名思义就是对tonmcat中的ServletContext资源的描述;ClassPathResource表示的类加载路径上的资源;ByteArrayResource表示的是字节数组资源。FileSystemResource和UrlResource的含义,上面已经说过了。
这个组件其实有两个功能其中一个功能是负责相关资源的加载,大家可以类比一下类加载器,这个功能有ResourceLoader体系完成,还有一个功能是资源的解析,而资源的解析是通过ResourceResolver(资源解析器)实现完成的。
而spring支持的几种加载的资源的方式有:
而spring实现几种加载资源的方式其实就是通过策略模式所实现的,对于不同的方式加载资源采用不同的策略。而且返回的Resource对象也不同,这个过程也同样在源码中有体现。
下面这是FileSystemResourceLoader获取资源的策略,返回的Resource是继承了FileSystemResource的FileSystemContextResource,同样的其他几种加载方式在源码中都是类似的结构,这里就不过多介绍了,之后spring系列的博客会有详细说明。
看下面类图,我们发现了,ResouceLoader有两个继承分支,这两个分支分别代表着资源加载和资源解析两种功能。
将Resouce对象转换成BeanDefinition对象,就是将内部资源数据转换成Spring Bean描述数据。这种转换的模式在Dom4j解析器中也有体现。
上面这个图中,是不完全的,在最新的spring版本中还加了一个GroovyBeanDefinitionReader,是用于构建groovy配置文件中的Bean信息的(这是一种新的定义bean的方式,个人觉得很少能用上,这里就不过多细说了,如果可以想了解的,可以去问度娘)。而PropertiesBeanDefinitionReader和XmlBeanDefinitionReader这两个类分别是构建.propertie文件中的bean对象和构建xml文件中bean对象。
将BeanDefinition对象注册到Bean容器中。
spring一共有AliasRegistry和SingletonBeanRegistry这两种体系,分别表示通过别名注册和单例注册,这两种注册在我们使用spring的时候应该深有体会。
是整个SpringIOC的核心组件,其他组件都是为Bean容器组件服务,但又不单纯为其服务。这个组件中装着Spring容器所管理的所有的Bean对象以及所需要的各种数据。其中BeanFactory有很多文章说他是一个初级容器,是因为这个这个容器的功能很简单,就是装Bean对象,是一个纯粹的容器,而ApplicationContext这个容器不单纯是用于装Bean,它还有着其他的功能,如Bean生命周期的管理等。
可以说BeanFactory是面向spring本身而言的,而ApplicationContext是面向用户而言的。
对于ApplicationContext它不仅继承了BeanFactory的功能还和应用环境有着藕断丝连的关系。因此的它被命名为应用上下文对象是非常的合适的。
ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了 BeanFactory 的功能。