Spring源码流程图

手写 Spring

Spring源码流程图_第1张图片

Spring 是啥

Java 中处处是对象,而 Spring 可认为是承载对象的容器,以及对象的管理者

管理的前提必定是需要充分了解这个对象,因此,对象的信息必不可少

对象信息集中式管理的好处:

  • 节省内存:对象的信息,就像原材料,需要时便创建
  • 扩展性:信息并不一定只是聚集在一处,在运行时获取对象的额外信息,使得创建的对象能力更加丰富,创造更多可能
  • 解耦,就像拆零件,可随时更换其他零件

万丈高楼平地起,如何设计一个 Spring 容器?

定义、注册、获取
  • 定义:定义对象的信息,我们将 Spring 中的实例化之后的对象称为 Bean,(例如你今天的计划),另外,我们将对象的信息(有哪些字段、方法)称为 BeanDefinition
  • 注册:将 BeanDefinition 注册到 Spring 容器中(将计划写到备忘录中)
  • 获取:BeanDifiniton 的获取(根据备忘录,根据对应时间点,知道要做什么事情)

现在我们有这样一个类

public class Demo {
  public void foo() {
    System.out.println("执行了Demo下的foo方法");
  }
}

Spring如何对其进行管理呢?

定义 BeanDefinition - 存储对象信息

public class BeanDefinition {
  private Class classInfo;
  public BeanDefinition(Class classInfo) {
    this.classInfo = classInfo;
  }
  public Class getClassInfo() {
    return classInfo;
  }
}

定义管理Bean的工厂,用于Bean定义的注册、获取

数据结构多用于处理同类数据,合理的组织结构,可以更加充分的利用数据,以及更快的获取所需信息

根据名称,获取对应对象信息,Map 再适合不过了

public class BeanFactory {
  private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
  public Object getBean(String name) throws InstantiationException, IllegalAccessException {
    Class classInfo = beanDefinitionMap.get(name).getClassInfo();
    return classInfo.newInstance();
  }
  public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
    beanDefinitionMap.put(name, beanDefinition);
  }
}

使用

public class Main {
  public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    // 1.初始化 BeanFactory
    BeanFactory beanFactory = new BeanFactory();
    // 1. 定义
    BeanDefinition beanDefinition = new BeanDefinition(Demo.class);
    // 2. 注册
    beanFactory.registerBeanDefinition("demo", beanDefinition);
    //3. 获取
    Demo demo = (Demo) beanFactory.getBean("demo");
    demo.foo();
  }
}

应用上下文

将类的信息定义在 XML 文件中,方便统一管理
使得我们可以


<beans>
    <bean id="demo" class="cn.foo.Demo"/>
beans>
// 1.初始化 BeanFactory
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
// 2. 获取Bean对象调用方法
Demo demo = applicationContext.getBean("demo", Demo.class);
demo.foo();

AbstrctApplicationContext 的 refresh 方法

1 创建BeanFacotry,并加载BeanDefinition
2 获取BeanFactory
3 添加 ApplicationContextAwareProcessor
4 调用BeanFactoryPostProcessor
5 添加 BeanPostProcessor
6 初始化事件调用者
7 注册所有事件,同时对事件进行实例化
8 提前实例化单例 Bean
9 调用容器刷新事件

关于BeanFactoryPostProcessor与BeanPostProcessor

它俩都是PostProcessor(后置处理器) ,别人忙完了才轮到它

BeanFactory 是与BeanDefinition相关的
Bean是和实例化之后的对象相关的
它俩在应用上下文的refresh()方法下,实例化自身之后(因为getBeanOfType内调用了getBean方法),一个是立即调用,一个是添加,等到createBean的时候再调用

BeanFactoryPostProcessor

实例化所有继承了BeanFactory后置处理器接口的Bean,
并调用postProcessBeanFactory(BeanFactory的后置处理方法),(实例化之后就立即调用)
提供修改 BeanDefinition 属性的机会

beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);

BeanPostProcessor

实例化所有继承了Bean后置处理器接口的Bean,
并添加到AbstractBeanFactory(抽象Bean工厂)的beanPostProcessors中
用于在getBean方法下的初始化方法前后的扩展

beanFactory.getBeansOfType(BeanPostProcessor.class);
beanFactory.addBeanPostProcessor(beanPostProcessor);

FactoryBean

FactoryBean:工厂Bean,用于创建Bean的Bean
可以这么认为,凡是实现了FactoryBean接口的Bean,一定有两个Bean,
一个是工厂Bean本身,另一个是工厂Bean创建出来的Bean

工厂Bean在getBean方法的时候,
会调用并返回(如果factoryBeanObjectCache不存在的话)
FactoryBean接口下的getObject方法、该方法的返回值

代理的本质

代理的本质就是通过后置处理器,将拦截到的Bean进行一层代理,之后再返回对应代理对象

第五章

第六章

Spring源码流程图_第2张图片

第七章

你可能感兴趣的:(Java,spring,流程图,java)