1.ApplicationContext概述
Spring对ApplicationContext
的解释为:
BeanFactroy提供了容器的配置机制,可以管理任何类型的对象,而ApplicationContext扩展自BeanFactory,在此基础上,它增加了Spring AOP、国际化、事件发布等功能。
BeanFactory是面向框架本身的,而ApplicationContext是更加侧重于面向企业应用,可以说ApplicationContext是BeanFactory的超集。
2. UML
UML3. ApplicationContext
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
可以看到,ApplicationContext分别扩展了EnvironmentCapable
、ListableBeanFactory
、HierarchicalBeanFactory
、MessageSource
、ApplicationEventPublisher
、ResourcePatternResolver
,关于ListableBeanFactory
和HierarchicalBeanFactory
这里就不重复介绍了,今天介绍一下剩余的几个接口:
- EnvironmentCapable
这里做一个小插曲:
capable
->能力,以后看到某个接口包含了Capable,可以理解为声明某某能力的意思。
提供访问应用程序运行环境的能力,主要对profiles和properties建模。profiles是一个概要文件,你可以在程序中
@Profile
来指定当前程序处于什么状态,通常在企业开发中,profile代表不同的运行环境:dev、test、prod等properties是更为重要的角色,它的来源可以来自:properties files、JVM系统属性、环境变量、JNDI、servlet上下文属性等
- MessageSource
解析消息的策略类,支持消息的参数化和国际化,
- ApplicationEventPublisher
事件发布,应用了观察者模式
- ResourcePatternResolver
加载资源文件,支持ant的路径规则,例如常见的一些资源文件:"/WEB-INF/*-context.xml",继承自ResourceLoader,关于ResourceLoader,这里不做详细介绍,它是一个解析资源的策略类,根据不同的策略加载不同的资源。
4. 容器实现类
4.1 ApplicationContext概览
ApplicationContext声明的方法都是只读性的。
4.2 Lifecycle
用来控制Bean/容器本身的生命周期
4.3 ConfigurableApplicationContext概览
Spring为了让容器具备可配置化,声明了ConfigurableApplicationContext
的扩展接口,
该接口提供了对ApplicationContext的写方法:
不仅如此,它还声明了模板方法refresh
,控制上下文的close
。
4.4 常见实现
- FileSystemXmlApplicationContext:独立XML应用程序上下文,从文件系统或URL中获取上下文定义文件,将纯路径解释为相对文件系统位置.
- ClassPathXmlApplicationContext:默认从classPath进行资源加载.
- XmlWebApplicationContext:Web容器,从xml中获取配置,加载XmlBeanDefinition,默认情况下,从"/WEB-INF/applicationContext.xml"获取上下文配置。SSM项目中经常用到
- AnnotationConfigWebApplicationContext:基于注解的Web应用容器
5. 基于XML和注解的容器不同之处
xml的容器是基于xml配置来解析BeanDefinition的,而基于注解的则要指定一个启动类,配置组件扫描。
6. refresh
refresh是所有容器都需要实现的方法。Spring用ConfigurableApplicationContext
声明了refresh
方法,在抽象类AbstractApplicationContext
中声明了模板方法refresh
。该方法包含:
- prepareRefresh:准备此上下文以进行刷新,设置其启动日期和活动标志以及执行属性源的任何初始化。
-
obtainFreshBeanFactory:通知子类启动
refreshBeanFactory
,子类必须实现refreshBeanFactory
-
prepareBeanFactory:从Spring容器获取BeanFactory(Spring Bean容器)并进行相关的设置为后续的使用做准备,例如:
ClassLoader
-
postProcessBeanFactory:允许子类注册特殊的
BeanPostProcessors
,钩子方法 - invokeBeanFactoryPostProcessors:激活在容器中注册为bean的工厂处理器。
- registerBeanPostProcessors:注册Bean创建的后置处理器
- initMessageSource:初始化国际化配置
- initApplicationEventMulticaster:在Spring容器中初始化事件广播器,事件广播器用于事件的发布。
- onRefresh:设置内置的Web容器,如:Tomcat、Jetty、Undertow
- registerListeners:把Spring容器内的时间监听器和BeanFactory中的时间监听器都添加的事件广播器中。
- finishBeanFactoryInitialization:实例化BeanFactory中已经被注册但是未实例化的所有实例(懒加载的不需要实例化)
-
finishRefresh:发布相应的事件,例如:
ContextRefreshedEvent
.
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
refresh是一个模板方法的应用,子类可以重写上述的12个方法中的abstract方法,进行不同行为的表达,最后容器就会调用refresh加载不同实现类的方法。
总结
ApplicationContext在BeanFactory的基础上继续扩展,提供了应用级别的能力声明,其主要能力在AbstractApplicationContext
得以体现,包括:系统资源管理、资源解析、事件发布、国际化、容器初始化和前后置处理器的支持、容器生命周期管理等等。
不仅如此,从庞大的类结构你可以看到,Spring包含了很多设计原则:单一职责、开闭原则、面向接口原则等等。正是这种大师级别的容器实现,才能让Spring Framework可以兼容灵活性、扩展性。
最后,放一张对比图,从中概览BeanFactory和ApplicationContext的区别:
网友评论