手写简易 Spring(三)

文章详细阐述了如何实现Spring中Bean的初始化和销毁方法,包括通过XML配置的init-method和destroy-method,以及InitializingBean和DisposableBean接口。此外,还介绍了Aware接口让Bean感知容器对象,Bean的作用域定义,以及FactoryBean的扩展功能和管理。最后,文中提及了自己的代码结构,模拟了Spring的部分源码实现。
摘要由CSDN通过智能技术生成

三. 手写简易 Spring(三)

1. Bean 对象初始化和销毁方法

1. XML 添加 init-method 与实现 InitializingBean 接口注册初始化

  • 核心实现类 XmlBeanDefinitionReader:添加解析 XML 的 init-method 的参数放入 BeanDefinition 对象
  • 核心抽象类 AbstractAutowireCapableBeanFactory:在调用 invokeInitMethod 方法初始化时先判断是否有 InitializingBean 初始化,再判断是否有 init-method 初始化,同时避免调用两次相同方法

2. XML 添加 destroy-method 与实现 DisposableBean 接口注册销毁

  • 核心实现类 XmlBeanDefinitionReader:添加解析 XML 的 destroy-method 的参数放入 BeanDefinition 对象
  • DisposableBeanAdapter 类使用了适配器的设计模式,将俩销毁方法整合在一起
    • 先判断是否有 DisposableBean 销毁,再判断是否有 destroy-method 初销毁,同时避免调用两次相同方法
  • 核心抽象类 AbstractAutowireCapableBeanFactory:在初始化后调用 registerDisposableBeanIfNecessary 方法
    • 方法调用 DefaultSingletonBeanRegistry 类、注册带销毁的 BeanDefinition 对象
    • 存在 DisposableBean 或 destroy-method 就是带销毁的 BeanDefinition 对象
  • 解析 XML 与预加载单例对象后,手动注册销毁钩子时,调用 DefaultSingletonBeanRegistry 类的 destroySingletons 方法
    • DefaultSingletonBeanRegistry 类存在所有销毁的 BeanDefinition 集合,依次删除、同时调用 DisposableBeanAdapter 类整合的 destroy 方法

3. DefaultSingletonBeanRegistry 优秀的解耦方法

  • ConfigurableBeanFactory 接口定义了 destroySingletons 方法
  • AbstractBeanFactory 实现了 ConfigurableBeanFactory 接口但自己极其子类并未实现此方法
  • AbstractBeanFactory 交给了父类 DefaultSingletonBeanRegistry 实现 destroySingletons 方法,DefaultSingletonBeanRegistry 并没有实现 ConfigurableBeanFactory 接口因此无需 @Override
  • 核心就是 A 继承 B实现 C 时,C 的接口方法由 A 继承的父类 B 实现

在这里插入图片描述

2. 定义标记类型 Aware 接口,实现感知容器对象

1. 定义

  • 允许 Bean 对象拿到 Spring 框架中的 BeanFactory、BeanClassLoader、BeanName、ApplicationContext 等
  • 我们可以定义 Aware 标记接口,通过 instanceof 判断
    • JDK 常用标记接口:Cloneable、Serializable、RandomAccess、Remote
  • 当前继承 Aware 的接口包括:BeanFactoryAware、BeanClassLoaderAware、BeanNameAware 和 ApplicationContextAware,获取对应对象
    • 前三者属于 BeanFactory,因此在 beans.factory 包下
    • ApplicationContextAware 属于 ApplicationContext,因此在 context 包下
    • ApplicationContext 需要像容器中注册 addBeanPostProcessor ,再由 createBean 调用 applyBeanPostProcessorsBeforeInitialization 时进行操作

2. ApplicationContextAwareProcessor 包装处理器

  • ApplicationContextAwareProcessor 实现 BeanPostProcessor 接口
    • 在 refresh() 方法操作时,把 ApplicationContext 注册到 BeanPostProcessor 容器
    • 在 createBean() 方法进行 BeanPostProcessor Before 处理时调用

3. Bean 对象作用域

1. 定义

  • 是否单例存放在 BeanDefinition 中,通过 ConfigurableBeanFactory 成员变量 SCOPE_SINGLETON、SCOPE_PROTOTYPE 来定义
  • 单例与否区别
    • DefaultListableBeanFactory#preInstantiateSingletons 单例才预初始化
    • AbstractAutowireCapableBeanFactory#createBean 创建完成对象后单例才放入到内存中
    • AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary 注册 Disposable 销毁方法单例才执行
  • 某个 Bean 对象是否单例,通过 XmlBeanDefinitionReader 解析 XML 文件校验

4. 扩展其他框架 FactoryBean

1. 定义

  • Spring 对外提供一个可以二次从 FactoryBean 的 getObject 方法中获取对象的功能,这样所有实现此接口的对象类(例如其他框架),就可以扩充自己的对象功能
    • MyBatis 就是实现了一个 MapperFactoryBean 类,在 getObject 方法中提供 SqlSession 执行 CRUD 方法的操作
  • createBean 执行对象实例化、属性填充、依赖加载、前置后置处理、初始化等操作后,就执行 FactoryBean 具体对象中的 getObject 对象

2. FactoryBeanRegistrySupport 处理 FactoryBean 注册管理

  • AbstractBeanFactory 抽象类继承 DefaultSingletonBeanRegistry 实现类,中间加一层 FactoryBeanRegistrySupport 抽象类,为了扩展出创建 BeanFactory 的能力
    • AbstractBeanFactory#doGetBean 方法获取 Bean 对象时,判断是否是 FactoryBean 的子类
      • 否返回当前的 Bean 对象
      • 是通过 FactoryBeanRegistrySupport#getObjectFromFactoryBean 方法获取 FactorBean 对象
  • FactoryBeanRegistrySupport 处理关于 FactoryBean 对象的注册管理,同时单例对象会进行缓存
    • 它通过实现 FactorBean 接口,实现的 isSingleton 方法判断是否单例,实现的 getObject 方法获取 Bean 对象

6. 我的代码结构

1. 整体设计结构

在这里插入图片描述

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

在这里插入图片描述

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

.
├── beans
│   ├── BeansException.java
│   ├── PropertyValue.java
│   ├── PropertyValues.java
│   └── factory
│       ├── Aware.java
│       ├── BeanClassLoaderAware.java
│       ├── BeanFactory.java
│       ├── BeanFactoryAware.java
│       ├── BeanNameAware.java
│       ├── DisposableBean.java
│       ├── FactoryBean.java
│       ├── HierarchicalBeanFactory.java
│       ├── InitializingBean.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
│       │   ├── DisposableBeanAdapter.java
│       │   ├── FactoryBeanRegistrySupport.java
│       │   ├── InstantiationStrategy.java
│       │   └── SimpleInstantiationStrategy.java
│       └── xml
│           └── XmlBeanDefinitionReader.java
├── context
│   ├── ApplicationContext.java
│   ├── ApplicationContextAware.java
│   ├── ConfigurableApplicationContext.java
│   └── support
│       ├── AbstractApplicationContext.java
│       ├── AbstractRefreshableApplicationContext.java
│       ├── AbstractXMLApplicationContext.java
│       ├── ApplicationContextAwareProcessor.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
│   ├── IUserDao2.java
│   ├── UserController.java
│   ├── UserDao.java
│   ├── UserService.java
│   └── UserService2.java
└── common
    ├── MyBean1FactoryPostProcessor.java
    ├── MyBean1PostProcessor.java
    ├── MyBean2FactoryPostProcessor.java
    ├── MyBean2PostProcessor.java
    └── ProxyBeanFactory.java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值