Spring5 源码分析

矫情吗;* 2022-03-02 01:13 352阅读 0赞

1 、什么是 IOC/DI ?

IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创
建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让
容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。
DI(Dependency Injection)依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说
就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。
先从我们自己设计这样一个视角来考虑:
对象和对象关系怎么表示?
可以用 xml,properties 文件等语义化配置文件表示。

描述对象关系的文件存放在哪里?
可能是 classpath,filesystem,或者是 URL 网络资源,servletContext 等。
回到正题,有了配置文件,还需要对配置文件解析。
不同的配置文件对对象的描述不一样,如标准的,自定义声明式的,如何统一?在内部需要有一个统一
的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。
如何对不同的配置文件进行解析?需要对不同的配置文件语法,采用不同的解析器

2 、Spring 核心容器体系结构

(1) BeanFactory
Spring Bean 的创建是典型的工厂模式,这一系列的 Bean 工厂,也即 IOC 容器为开发者管理对象
间的依赖关系提供了很多便利和基础服务,在 Spring 中有许多的 IOC 容器的实现供用户选择和使用,
其相互关系如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x4ejM1MjkwNzgzOQ_size_16_color_FFFFFF_t_70

其中 BeanFactory 作为最顶层的一个接口类,它定义了 IOC 容器的基本功能规范,BeanFactory 有三
个子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory。
但是从上图中我们可以发现最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接
口。那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,
它主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限
制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表
示的是这些 Bean 是有继承关系的,也就是每个Bean 有可能有父Bean。AutowireCapableBeanFactory

接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean
行为.
最基本的 IOC 容器接口 BeanFactory

  1. public interface BeanFactory {
  2. //对 FactoryBean 的转义定义,因为如果使用 bean 的名字检索 FactoryBean 得到的对象是工厂生成的对象,
  3. //如果需要得到工厂本身,需要转义
  4. String FACTORY_BEAN_PREFIX = "&";
  5. //根据 bean 的名字,获取在 IOC 容器中得到 bean 实例
  6. Object getBean(String name) throws BeansException;
  7. //根据 bean 的名字和 Class 类型来得到 bean 实例,增加了类型安全验证机制。
  8. <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
  9. Object getBean(String name, Object... args) throws BeansException;
  10. <T> T getBean(Class<T> requiredType) throws BeansException;
  11. <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
  12. //提供对 bean 的检索,看看是否在 IOC 容器有这个名字的 bean
  13. boolean containsBean(String name);
  14. //根据 bean 名字得到 bean 实例,并同时判断这个 bean 是不是单例
  15. boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
  16. boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
  17. boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
  18. boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
  19. //得到 bean 实例的 Class 类型
  20. @Nullable
  21. Class<?> getType(String name) throws NoSuchBeanDefinitionException;
  22. //得到 bean 的别名,如果根据别名检索,那么其原名也会被检索出来
  23. String[] getAliases(String name);
  24. }

在 BeanFactory 里只对 IOC 容器的基本行为作了定义,根本不关心你的 Bean 是如何定义怎样加载的。
正如我们只关心工厂里得到什么的产品对象,至于工厂是怎么生产这些对象的,这个基本的接口不关心。
而要知道工厂是如何产生对象的,我们需要看具体的 IOC 容器实现,Spring 提供了许多 IOC 容器
的实现。比如 XmlBeanFactory,ClasspathXmlApplicationContext 等。其中 XmlBeanFactory 就
是针对最基本的 IOC 容器的实现,这个 IOC 容器可以读取 XML 文件定义的 BeanDefinition(XML 文件中对 bean 的描述),如果说 XmlBeanFactory 是容器中的屌丝,ApplicationContext 应该算容器中
的高帅富.
ApplicationContext 是 Spring 提供的一个高级的 IOC 容器,它除了能够提供 IOC 容器的基本功
能外,还为用户提供了以下的附加服务。
从 ApplicationContext 接口的实现,我们看出其特点:
1.支持信息源,可以实现国际化。(实现 MessageSource 接口)
2.访问资源。(实现 ResourcePatternResolver 接口,后面章节会讲到)
3.支持应用事件。(实现 ApplicationEventPublisher 接口)

(2) BeanDefinition
SpringIOC 容器管理了我们定义的各种 Bean 对象及其相互的关系,Bean 对象在 Spring 实现中是
以 BeanDefinition 来描述的,其继承体系如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x4ejM1MjkwNzgzOQ_size_16_color_FFFFFF_t_70 1

Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵
活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。这个解析过程主要通过下
图中的类完成:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x4ejM1MjkwNzgzOQ_size_16_color_FFFFFF_t_70 2

发表评论

表情:
评论列表 (有 0 条评论,352人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Spring分析

    前言 作为一名开发人员,阅读源码是一个很好的学习方式。本文将结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码,若有描述错误之处,欢迎指正。 ...

    相关 Spring5 分析

    1 、什么是 IOC/DI ? IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建、依赖的代码,反转