SpringIOC源码解析(3)—— 高级容器

192 阅读3分钟

ApplicationContext家族体系

请添加图片描述 高级容器均实现了ApplicationContex这个接口,为了区别于普通容器,高级容器一般被称为Contex(上下文),之所以是高级容器,因为它实现了更多的接口: 请添加图片描述

ApplicationContex继承的接口

请添加图片描述 Environment可以理解为容器的一些启动参数,类如java里的 -Dparam1=value1 对于web容器,还可以根据此获取到servlet的一些配置信息

继承了ListableBeanFactory意味着可以根据列表的方式管理bean

继承了HierarchicalBeanFactory意味着可以基于多层级的结构来实现每一层级对bean的管理

继承了ResourcePatternResolver可以加载资源文件,相当于ResourceLoader,分析beandefinition加载的时候会提到

继承了MessageSource可以管理一些Message,实现国际化等功能

继承了ApplicationEventPublisher可以具备事件发布的能力,容器启动的时候会注册一些Listener,就是用来监听容器发布的事件的(观察者设计者模式)

ApplicationContext常用容器

传统的基于XML配置的经典容器

  • FileSystemXmlApplicationContext:从文件系统加载配置
  • ClassPathXmlApplicationContext:从classpath加载配置
  • XmlWebApplicationContext:用于Web应用程序的容器

目前比较流行的容器(都是基于注解的)

  • AnnotationConfigServletWebServerApplicationContext
    • 在springboot的boot模块下
  • AnnotationConfigReactiveWebServerApplicationContext
    • 满足响应式容器需求,在springboot的boot模块下
  • AnnotationConfigApplicationContext
    • spring框架里,普通的非web应用基本都用这个

容器的共性

refresh()大致功能:

  • 容器初始化、配置解析
  • BeanFactoryPostProcessor和BeanPostProcessor的注册和激活
  • 国际化配置

ApplicationContext源码

请添加图片描述 都是一些get方法,只读的,所以还要利用子接口来实现它的可配置的能力

ConfigurableApplicationContext有一些set方法用来配置ApplicationContext 请添加图片描述 请添加图片描述 它继承了Lifecycle有start、stop等方法用于对容器的生命周期管理。Closeable是jdk相关接口,用于关闭容器时释放相关资源。

主要提供了refreshclose方法,refresh是主流容器都要做的事情,ApplicationContext被关闭时,refresh可重新启动容器,重新调用它会清除缓存、重新装载配置信息。

ConfigurableApplicationContext的最主要的实现类是AbstractApplicationContext,也是高级容器中最主要的类,实现了ApplicationContext接口中简单、不易动的部分,主要是容器工厂的处理: 请添加图片描述 发布事件 请添加图片描述 监听器的注册 请添加图片描述 容器初始化操作refresh方法 请添加图片描述 getBean方法 请添加图片描述 等等所有容器相关的方法,没有实现的也预留出了抽象方法以供子容器实现

模板方法设计模式

请添加图片描述 例如:

package demo.pattern.template;

public abstract class KTVRoom {
    public void procedure(){
        openDevice();
        orderSong();
        orderExtra();
        pay();
    }
    //模板自带方法,使用前必须得打开设备
    private void openDevice(){
        System.out.println("打开视频和音响");
    }
    //子类必须实现的方法,必须得选歌
    protected abstract void orderSong();
    //钩子,额外开销视情况选择
    protected void orderExtra(){};
    //模板自带方法,用后必须得付款
    private void pay(){
        System.out.println("支付本次的消费账单。。。");
    }
}

AbstractApplicationContext的refresh方法便是模板设计模式的一个很好的实践,refresh本身就是一个模板方法,主要定义了ApplicationContext下面的容器启动的时候要做什么事情:

  1. prepareRefresh()方法,具体的实现由AbstractApplicationContext自己定义 请添加图片描述
  2. obtainFreshBeanFactory(),里面的两个方法都是抽象方法,强制ApplicationContext的子类必须实现

请添加图片描述 3. prepareBeanFactory(beanFactory),为容器的某些子类指定特殊的BeanPost事件处理器,勾子方法 请添加图片描述