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相关接口,用于关闭容器时释放相关资源。
主要提供了refresh和close方法,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下面的容器启动的时候要做什么事情:
prepareRefresh()方法,具体的实现由AbstractApplicationContext自己定义
obtainFreshBeanFactory(),里面的两个方法都是抽象方法,强制ApplicationContext的子类必须实现
3. prepareBeanFactory(beanFactory),为容器的某些子类指定特殊的BeanPost事件处理器,勾子方法