> 文章列表 > 手写简易 Spring(二)

手写简易 Spring(二)

手写简易 Spring(二)

文章目录

  • 手写简易 Spring(二)
  • 1. 扩展 BeanFactory 接口
  • 2. 实现资源加载器,从 Spring.xml 解析和注册 Bean 对象
    • 1. 核心实现类 XmlBeanDefinitionReader
  • 3. 实现应用上下文,自动识别、资源加载、扩展机制
    • 1. 应用上下文
    • 2. 核心实现类 ClassPathXmlApplicationContext
    • 3. Bean 实例化前后修改与扩展
  • 4. 我的代码结构
    • 1. 整体设计结构
    • 2. 我的调用类图(模拟 Spring 源码)
    • 3. 我的代码结构(模拟 Spring 源码)

手写简易 Spring(二)

1. 扩展 BeanFactory 接口

  • 接口 ConfigurableListableBeanFactory:提供分析和修改 Bean 对象以及预先实例化的操作接口

    • 接口 ListableBeanFactory:扩展 BeanFactory 的接口,提供了所有的 Bean 对象基本信息的方法
    • 接口 ConfigurableBeanFactory:注册与获取 BeanPostProcessor、BeanClassLoader 等的一个配置化接口
      • 接口 HierarchicalBeanFactory:扩展了 BeanFactory,提供了父容器访问功能的方法
    • 接口 AutowireCapableBeanFactory:扩展了 BeanFactory,提供了自动装配、前、后处理器等接口,可以使用这个接口集成其它框架
  • 我的代码类图

在这里插入图片描述

2. 实现资源加载器,从 Spring.xml 解析和注册 Bean 对象

1. 核心实现类 XmlBeanDefinitionReader

  • 核心实现类 XmlBeanDefinitionReader:解析 XML 文件、获取 Bean 配置以及配置中的 id、name、class、value、ref,设置属性与注册 BeanDefinition

    • 接口 BeanDefinitionReader:BeanDefinition 读取接口,定义:getRegistry()、getResourceLoader(),与三个加载 BeanDefinition 的方法
  • 实现类 DefaultResourceLoader:资源加载器实现类,通过策略模式:外部传入地址即可获取对应 Resource,而不用管具体那种流文件

    • 接口 ResourceLoader:资源加载器接口
  • 接口 Resource:处理资源加载流,提供获取 InputStream 流的方法,也可看做 classPath、FileSystem、URL 三种方式获取流的适配器

    • 实现类 FileSystemResource:FileSystem 流文件获取数据
    • 实现类 ClassPathResource:ClassPath 流文件获取数据
    • 实现类 UrlResource:Url 流文件获取数据
  • 我的代码类图

在这里插入图片描述

3. 实现应用上下文,自动识别、资源加载、扩展机制

1. 应用上下文

  • 应用上下文的一系列的流程
    • 加载 XML
    • 注册 BeanDefinition
    • 修改定义(BeanFactoryPostProcessor)
    • 实例化
    • 属性填充
    • 初始化与扩展初始化(BeanPostProcessor)

2. 核心实现类 ClassPathXmlApplicationContext

  • 接口 ApplicationContext:继承了 ListableBeanFactory 接口,即扩展了 BeanFactory 的功能,是一个核心接口
  • 接口 ConfigurableApplicationContext:继承了 ApplicationContext 接口,定义了核心方法 refresh 方法、用于刷新容器
  • 抽象类 AbstractApplicationContext:实现了 refresh、invokeBeanFactoryPostProcessors、registerBeanPostProcessors 方法,定义了 refreshBeanFactory、getBeanFactory 方法
    • 继承了 DefaultResourceLoader 类:子类可用于加载 XML 文件
    • 实现了 ConfigurableApplicationContext 接口:实现 refresh 方法
      • 创建 BeanFactory,加载 BeanDefinition
      • 获取 BeanFactory
      • 执行 BeanFactoryPostProcessor,此时为 Bean 初始化之前
      • 注册 BeanPostProcessor,此时为 Bean 初始化之前
      • 提前实例化单例 Bean 对象
  • 抽象类 AbstractRefreshableApplicationContext:继承了 AbstractApplicationContext 类,创建与获取 DefaultListableBeanFactory、实现 refreshBeanFactory 方法,定义 loadBeanDefinitions 方法
  • 抽象类 AbstractXMLApplicationContext:继承了 AbstractRefreshableApplicationContext 类,实现了 loadBeanDefinitions 方法,定义了 getConfigLocations 方法
  • 核心实现类 ClassPathXmlApplicationContext:继承了 AbstractXMLApplicationContext 类,实现了 getConfigLocations 方法
    • 具体对外提供应用上下文的核心类
  • 核心抽象类 AbstractAutowireCapableBeanFactory:增加实现 AutowireCapableBeanFactory 接口,实现了 initializeBean 接口
    • initializeBean 接口:执行 BeanPostProcessor 前置处理器方法、执行 invokeInitMethods 方法,执行 BeanPostProcessor 后置处理器方法、返回覆盖 Bean 对象
  • 核心实现类 DefaultListableBeanFactory:增加实现了 ConfigurableListableBeanFactory 接口,实现了 getBeansOfType、preInstantiateSingletons 方法
    • 核心实现类 AbstractBeanFactory:增加实现了 ConfigurableBeanFactory 接口,实现了 addBeanPostProcessor 方法

3. Bean 实例化前后修改与扩展

  • BeanFactoryPostProcessor 接口:BeanDefinition 注册后、初始化之前的操作,可以修改 BeanDefinition 的信息
  • BeanPostProcessor 接口:每个 Bean 初始化前后均可操作,可以扩展 Bean 功能甚至替换 Bean 对象,与 AOP 有紧密联系

4. 我的代码结构

1. 整体设计结构

在这里插入图片描述

2. 我的调用类图(模拟 Spring 源码)

在这里插入图片描述

3. 我的代码结构(模拟 Spring 源码)

.
├── beans
│   ├── BeansException.java
│   ├── PropertyValue.java
│   ├── PropertyValues.java
│   └── factory
│       ├── BeanFactory.java
│       ├── HierarchicalBeanFactory.java
│       ├── ListableBeanFactory.java
│       ├── config
│       │   ├── AutowireCapableBeanFactory.java
│       │   ├── BeanDefinition.java
│       │   ├── BeanFactoryPostProcessor.java
│       │   ├── BeanPostProcessor.java
│       │   ├── BeanReference.java
│       │   ├── ConfigurableBeanFactory.java
│       │   ├── ConfigurableListableBeanFactory.java
│       │   └── SingletonBeanRegistry.java
│       ├── support
│       │   ├── AbstractAutowireCapableBeanFactory.java
│       │   ├── AbstractBeanDefinitionReader.java
│       │   ├── AbstractBeanFactory.java
│       │   ├── BeanDefinitionReader.java
│       │   ├── BeanDefinitionRegistry.java
│       │   ├── CglibSubclassingInstantiationStrategy.java
│       │   ├── DefaultListableBeanFactory.java
│       │   ├── DefaultSingletonBeanRegistry.java
│       │   ├── InstantiationStrategy.java
│       │   └── SimpleInstantiationStrategy.java
│       └── xml
│           └── XmlBeanDefinitionReader.java
├── context
│   ├── ApplicationContext.java
│   ├── ConfigurableApplicationContext.java
│   └── support
│       ├── AbstractApplicationContext.java
│       ├── AbstractRefreshableApplicationContext.java
│       ├── AbstractXMLApplicationContext.java
│       └── ClassPathXmlApplicationContext.java
├── core
│   └── io
│       ├── ClassPathResource.java
│       ├── DefaultResourceLoader.java
│       ├── FileSystemResource.java
│       ├── Resource.java
│       ├── ResourceLoader.java
│       └── UrlResource.java
└── utils├── ClassUtils.java└── StringUtils.java
.
├── ApiTest.java
├── bean
│   ├── UserController.java
│   ├── UserDao.java
│   └── UserService.java
└── common├── MyBean1FactoryPostProcessor.java├── MyBean1PostProcessor.java├── MyBean2FactoryPostProcessor.java└── MyBean2PostProcessor.java