【Spring 源码学习】IOC 容器源码环境与简单测试

「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」。


一,前言

本篇,原定要写 IOC 容器接口继承体系,已经写好了几天,只还是没发出来; 还是觉得应该先写一个 IOC 容器的简单 Demo,介绍一下使用; 顺便也为不熟悉 Spring 框架的朋友们降低一下学习门槛;

对于 Spring 框架的学习,不仅是了解框架内部实现,有助于日常开发; 更多的还是学习框架的设计思想以及优秀代码是如何架构、分层和实现的; Spring 框架中使用的设计模式堪称最佳实践,是非常具有学习价值的;

本篇,对于已经熟悉 Spring 框架的朋友,几乎是一篇废话。。。


二,IOC 容器的源码环境

之前说了 Spring 框架源码环境的搭建,Spring 框架提供了根据应用场景的剪裁和选择;

研究 IOC 容器部分,可以只使用 Spring 框架的 IOC容器部分即可,即源码中的 spring-beans 模块;

IOC 容器依赖模块:

IOC 容器功能的实现主要在 org.Springframework.beans.jar 中,即 spring-beans 模块;
而 spring-beans 依赖于 spring-core 模块;
IOC 容器部分,只需要依赖 spring-beans 和 spring-beans 即可;
复制代码

创建 IOC 容器工程:

创建 java 工程 IocContainer,使其依赖 spring-beans 和 spring-beans 两个模块;
复制代码

项目结构:

java工程IocContainer

项目模块依赖关系:

IOC项目依赖关系


三,测试 IOC 容器

为了测试 IOC 容器,我们写一个最简单的 Demo,项目结构如下:

IOC容器项目目录

1.Bean:MyTestBean.java

Spring 的目的就是让 bean 能够成为一个纯粹的POJO(Plain Ordinary Java Object 简单的Java对象)
复制代码
package com.brave.spring.beans;

public class MyTestBean {

    private String testStr = "testStr";

    public String getTestStr() {
            return testStr;
    }

    public void setTestStr(String testStr) {
            this.testStr = testStr;
    }
}
复制代码

2.配置文件:beanFactoryTest.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"  
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">        
    <!-- 声明一个bean(com.brave.spring.beans.MyTestBean),id属性为MyTestBean -->
    <bean id="MyTestBean" class="com.brave.spring.beans.MyTestBean"/>
</beans>
复制代码
  • 以上虽然是一个最简单的 bean 声明方式,但能够满足大多数应用的需要;
  • Spring 配置中的 bean 元素还提供了 N 多种属性,可以适配各种应用场景,后续会逐个讲解;

3.测试类:BeanFactoryTest.java

package com.brave.spring.beans;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class BeanFactoryTest {

    public static void main(String[] args) {
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

        MyTestBean bean = (MyTestBean)xmlBeanFactory.getBean("MyTestBean");

        String testStr = bean.getTestStr();
        System.out.print("testStr = " + testStr);
    }
}
复制代码
从命名可以看出,这是一个对 bean 工厂的测试,主要逻辑如下:

1,读取配置文件beanFactoryTest.xml
2,根据beanFactoryTest.xml中的配置(id)在Bean工厂中找到对应类的配置,并实例化
3,调用实例

备注:关于 Demo 中 xmlBeanFactory 的详细实现,也是我们日后要说的重点;
复制代码

四,IOC容器的一些概念

以上,创建了一个只拥有 IOC 容器功能的 Spring 工程
虽然实现了 Spring-IOC 容器下,通过配置文件创建和使用bean,
但概念上还需要再细说一下,对于日后学习源码会有帮助
复制代码

理解"容器"

说到容器,应该能想到水壶、水杯、水桶之类,都是装水的容器;
而 IOC 容器,即 Bean 容器(BeanFactory),就是装 bean 的容器;

所以,可以将 Bean 容器想象成一个水桶,而其中的 bean 就是水桶中的水;
bean 容器中装载的无数 Bean,就相当于水桶中的无数水滴;
复制代码

Spring 中的容器

尽管水桶有大小和材质上的区别,但统称为水桶;
对于水桶的定义:能装水的桶就叫水桶,所以重点还是在于能装水;
站在面向对象的角度,"水桶"就应该实现"能装水"的接口;

Spring 中也为我们提供了多种 BeanFactory 的实现,
Spring 中如何定义 BeanFactory?必须要实现 BeanFactory 接口
BeanFactory 接口定义了 Bean 容器的基本功能
如:Demo 中的 xmlBeanFactory,在实现了 BeanFactory 接口的基础上,增加了通过 XML 文件获取资源定位的能力;

后续讲解容器接口体系时,会主要讲解两类 BeanFactory:
- 一类是基于 BeanFactory 实现的容器,这一类容器称为"基本容器";
- 另一类是基于 ApplicationContext 实现的容器,这一类容器称为"高级容器";
复制代码

bean 如何放入容器

Spring 提供了多种定义 bean 的方式,如:xml方式、注解方式等;
对于容器(水桶)而言,不管以何种方式定义 bean,最终在容器中都是以同一种对象(水)存在;

Spring 通过 BeanDefinition 抽象了对Bean的定义,BeanDefinition 也是容器的主要数据类型;
BeanDefinition 即为 Bean 容器中的"水"

Spring 用过各种资源加载器,获取定义 Bean 的资源定位,将其转换为BeanDefinition,放入 BeanFactory;
复制代码

五,结尾

本篇暂时先写到这里,虽然没有什么营养,但也为日后学习做了铺垫;
这个 Demo 依赖了 spring-bean 和 spring-core 的源码;
也是日后学习这部分源码的重要工程

关于容器理解的部分日后会继续补充的完善
复制代码

猜你喜欢

转载自juejin.im/post/7031192845687980039