Spring5 - 30个类手写实战 - 打卡第五天(手绘IOC时序图)

相关文章:
Spring5 - 30个类手写实战 - 打卡第一天(V1版本)

Spring5 - 30个类手写实战 - 打卡第二天(IOC与DI)

Spring5 - 30个类手写实战 - 打卡第三天(MVC)

Spring5 - 30个类手写实战 - 打卡第四天(AOP)

1. IOC&DI

IOC(Inversion of Control) : 控制反转,所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。

DI(Dependency Injection):依赖注入,就是指对象是被动接受依赖类而不是自己主动去找,换句话说就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给他。

完成BeanDefinition的注册,放在beanDefinitionMap。

  • ApplicationContext (入口)
    ClassPathXmlApplicationContext
    AnnotationConfigApplicationContext
    WebApplicationContext
  • BeanDefinition
    XmlBeanDefinition
  • BeanDefinitionReader
    XmlBeanDefinitionReader

对象与对象的关系怎么表示?XML/YML/properties
描述对象关系的文件放在哪里?classpath/network/filesystem/servletContext/annotation
统一配置文件的标准?BeanDefinition
如何对不同的配置文件进行解析?策略模式

2.基于XML的IoC容器的初始化

IoC容器初始化大致分为三个步骤:
在这里插入图片描述

  • 定位
    定位配置文件和扫描相关的注解
  • 加载
    将配置信息载入到内存中
  • 注册
    根据载入的信息,将对象初始化到IOC容器

可详细划分为以下步骤:

在这里插入图片描述

IOC容器初始化的详细基本步骤:

  1. 初始化的入口在容器实现中的refresh()调用来完成
  2. 对Bean定义载入IOC容器使用的方法时loadBeanDefinition(),其中的大致流程如下:通过ResourceLoader来完成资源文件的定位,DefaultResourceLoader是默认的实现,同时上下文本身就给出了ResourceLoader的实现,可以从类路径,文件系统,URL等方式来定位资源位置。如果是XmlBeanFactory作为IOC容器,那么需要为它指定Bean定义的资源,也就是说Bean定义文件时通过抽象成Resource来被IOC容器处理的,容器通过BeanDefinitionReader来完成定义信息的解析和Bean信息的注册,往往使用的是XmlBeanDefinitionReader来解析Bean的XML定义文件-实际的处理过程是委托给BeanDefinitionParserDelegate来完成的,从而得到bean的定义信息,这些信息在Spring中使用BeanDefinition对象来表示,这个名字可以让我们想到loadBeanDefinition(),registerBeanDefinition()这些相关的方法。他们都是为处理BeanDefinition服务的,容器解析得到BeanDefinition以后,需要把它在IOC中注册,这由IOC实现BeanDefinitionRegistry接口来实现。注册过程就是在IOC容器内部维护一个HashMap来保存得到的BeanDefinition的过程。这个HashMap是IOC容器持有Bean信息的场所,以后对Bean的操作都是围绕这个HashMap来实现的。
  3. 然后我们就可以通过BeanFactory和ApplicationContext来享受到Spring IOC的服务了,在使用IOC容器的时候,我们注意到除了少量粘合代码,绝大多数以正确IOC风格编写的应用程序代码完全不用关心如何到达工厂,因为容器把这些对象与容器管理的其他对象关联在一起。基本的策略是把工厂放到已知的地方,最好是放在对预期使用的上下文有意义的地方,以及代码将实际需要访问工厂的地方。Spring本身提供了对申明式载入web应用程序用法得到采用程序上下文,并将其存储在ServletContext中的框架实现。

下面是容器初始化的简单时序图:

在这里插入图片描述

3. 基于Spring源码对之前代码调整

采用Spring的结构,LApplicationContext继承LBeanFactory,创建LDefaultListableBeanFactory也继承LBeanFactory,并将beanDefinitionMap以及getBean方法从LApplicationContext转移到LDefaultListableBeanFactory中。

LBeanFactory

package com.liulin.spring.framework.core;

/**
 * Create by DbL on 2020/5/4 0004
 */
public interface LBeanFactory {
    public Object getBean(String beanName);

    public Object getBean(Class beanClass);
}

LDefaultListableBeanFactory

package com.liulin.spring.framework.beans.support;

import com.liulin.spring.framework.beans.config.LBeanDefinition;
import com.liulin.spring.framework.core.LBeanFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Create by DbL on 2020/5/4 0004
 */
public class LDefaultListableBeanFactory implements LBeanFactory {

    public Map<String, LBeanDefinition> beanDefinitionMap = new HashMap<String, LBeanDefinition>();

    @Override
    public Object getBean(String beanName) {
        return null;
    }

    @Override
    public Object getBean(Class beanClass) {
        return null;
    }

    public  void doRegistBeanDefinition(List<LBeanDefinition> beanDefinitions) throws Exception {
        for (LBeanDefinition beanDefinition : beanDefinitions) {
            if (this.beanDefinitionMap.containsKey(beanDefinition.getFactoryBeanName())) {
                throw new Exception("The " + beanDefinition.getFactoryBeanName() + " is Exists");
            }
            beanDefinitionMap.put(beanDefinition.getFactoryBeanName(), beanDefinition);
            beanDefinitionMap.put(beanDefinition.getBeanClassName(), beanDefinition);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值