【从零构建Spring|第一节】 构建简单Bean容器

【从零构建Spring|第一节】 构建简单Bean容器

前言

每每谈到 Spring 框架,大家总会涉及一些高大上的名词,比如 IOC 控制反转、DI 依赖注入、AOP 面向切面等等,但却忘记了最基本的一点。 Spring 的本质是一个 Bean 工厂(beanFactory)或者说 Bean 容器

它按照我们的要求,生产我们需要的各种各样的bean,提供给我们使用。只是在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术。也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已

为什么需要Spring框架来给我们提供这个 beanFactory 的功能呢?原因是一般我们认为是,可以将原来硬编码的依赖,通过 Spring 这个 beanFactory 这个工厂来注入依赖,也就是说原来只有依赖方和被依赖方,现在我们引入了第三方—— Spring 这个 beanFactory,由它来解决bean之间的依赖问题,达到了松耦合的效果;

这个只是原因之一,还有一个更加重要的原因:在没有 Spring 这个 beanFactory 之前,我们都是直接通过 new 来实例化各种对象,现在各种对象 bean 的生产都是通过 beanFactory 来实例化的,这样的话, Spring 这个 beanFactory 就可以在实例化 bean 的过程中,做一些小动作——在实例化bean的各个阶段进行一些额外的处理,也就是说 beanFactory 会在 bean 的生命周期的各个阶段中对 bean 进行各种管理,并且Spring 这些阶段通过各种接口暴露给我们,让我们可以对 bean 进行各种处理,我们只要让 bean 实现对应的接口,那么 Spring 就会在 bean的生命周期调用我们实现的接口来处理该 bean

设计

image-20230221155314512

简单定义 BeanFactoryBeanDefinition

  • BeanFactory:是最基层、最顶级的 BeanFactory。提供 Bean 的生产和管理方法,当然目前来说他是不完善的,在第二节中,会将它设置成接口,仅提供方法,规范代码的简洁性
  • BeanDefinition:是 Bean 定义元数据,当前的实现是直接将 Bean 对象整个类存入 BeanDefinition。后续章节会将他的职责抽象为存储 Bean 对象的名称、类型和属性。

创建 Bean:

@Test
public void test_BeanFactory() {
// 1. 初始化 BeanFactory
BeanFactory beanFactory = new BeanFactory();

// 2. 注入 Bean
BeanDefinition beanDefinition = new BeanDefinition(new UserService());
beanFactory.registerBeanDefinition("userService", beanDefinition);

// 3. 获取 Bean
UserService userService = (UserService) beanFactory.getBean("userService");
userService.queryUserInfo();
}

一个最最最简单的 Spring IOC 实现就是如此,BeanFactory 提供 Bean 的生产和管理,BeanDefinition 存储 Bean 对象。当然目前来说是很不完善的,甚至是错误的。他甚至没有涉及到 Spring IOC 的核心思想 —— 控制反转依赖注入,但这样一个小例子,正是 Spring IOC 的核心内容(不是思想),后续的章节皆为完善与扩展知识

思考

为什么说 Spring 是非侵入式的?

因为对于任何一个不懂 Spring 底层的程序员来说,只要他能熟练使用xml或者 注解方式(Spring底层称之为 resource)标注 beanSpring 通过 resourceLoader resource 解析成各种层次的组件清单,再将其加载到 BeanDefinitionReader

可以认为 xml、注解 就是 Spring 制造 bean 对象的 蓝图Spring 通过 resourceLoader

读取我们对将要构造的Bean的需求, 并进行统一的创建与管理, 也就是说我们只需要引入Spring的依赖, 并将元数据配置到xml或注解中, 就可以无缝将Spring集成到现有的Java应用程序中, 不需要更改业务代码或者依赖于各种API 或者 接口