在使用Spring的时候,咱们常常须要先获得一个ApplicationContext对象,而后从该对象中获取咱们配置的Bean对象。ApplicationContext隶属于org.springframework.context,是SpringFramework中Bean的管理者,为SpringFramework的诸多功能提供支撑做用。web
下图是Spring-4.3.2.RELEASE版本中ApplicationContext相关的UML类视图(浅绿色的为接口,浅黄色的为类):spring
public interface BeanFactory
BeanFactory 是 Spring 管理 Bean 的最顶层接口,是一个 Bean 容器, 管理一系列的 bean,每个 bean 使用一个String 类型的 name(或称之为id) 来惟一肯定,这些 Bean 能够是 prototype 的或者 singleton的 。Spring 提倡使用依赖注入(Dependency Injection) 的方式装配 Bean。BeanFactory从“configuration source”加载Bean的定义,configuration source 能够是xml文件或者properties文件甚至是数据库。数据库
public interface HierarchicalBeanFactory extends BeanFactory
BeanFactory的子接口HierarchicalBeanFactory是一个具备层级关系的Bean 工厂,拥有属性parentBeanFactory。当获取 Bean对象时,若是当前BeanFactory中不存在对应的bean,则会访问其直接 parentBeanFactory 以尝试获取bean 对象。此外,还能够在当前的 BeanFactory 中 override 父级BeanFactory的同名bean。编程
public interface ListableBeanFactory extends BeanFactory
ListableBeanFactory 继承了BeanFactory,实现了枚举方法能够列举出当前BeanFactory中全部的bean对象而没必要根据name一个一个的获取。 若是 ListableBeanFactory 对象仍是一个HierarchicalBeanFactory则getBeanDefinitionNames()方法只会返回当前BeanFactory中的Bean对象而不会去父级BeanFactory中查询。架构
public interface PropertyResolver
配置文件解析器的最顶级接口,解析配置文件获取属性值等做用框架
public interface Environment extends PropertyResolver
提供当前Application运行的所需环境ide
public interface EnvironmentCapable
这是一个Environment Holder,只有一个方法:Environment getEnvironment() 用来获取Environment对象函数
public interface ApplicationEventPublisher
该接口的功能是publish Event,向事件监听器(Listener)发送事件消息this
public interface MessageSource
解析message的策略接口,方法形如: String getMessage(String, Object[], String, Locale),用于支撑国际化等功能spa
public interface ResourcePatternResolver extends ResourceLoader
其中ResourceLoader用于从一个源(如InputStream等)加载资源文件,ResourcePatternResolver 是ResourceLoader的子类,根据 path-pattern 加载资源。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver
重点来了,ApplicationContext接口继承众多接口,集众多接口功能与一身,为Spring的运行提供基本的功能支撑。根据程序设计的“单一职责原则”,其实每一个较顶层接口都是“单一职责的”,只提供某一方面的功能,而ApplicationContext接口继承了众多接口,至关于拥有了众多接口的功能,下面看看它的主要功能:
ApplicationContext 接口具备两个直接子接口,分别是:
org.springframework.context.ConfigurableApplicationContext org.springframework.web.context.WebApplicationContext
分别看这两个子接口:
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable
根据接口名能够判决,该接口是可配置的!ApplicationContext 接口自己是 read-only 的,因此子接口 ConfigurableApplicationContext 就提供了如setID()、setParent()、setEnvironment()等方法,用来配置ApplicationContext。
再看其继承的另外两个接口:
public interface WebApplicationContext extends ApplicationContext
该接口仅仅在原接口基础上提供了getServletContext(),用于给servlet提供上下文信息。
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext
这里 ConfigurableWebApplicationContext 又将上述两个接口结合起来,提供了一个可配置、可管理、可关闭的WebApplicationContext,同时该接口还增长了setServletContext(),setServletConfig()等set方法,用于装配WebApplicationContext。
到这里ApplicationContext相关接口基本上已经讲完了,总结起来就两大接口:
org.springframework.context.ConfigurableApplicationContext org.springframework.web.context.ConfigurableWebApplicationContext
对于普通应用,使用ConfigurableApplicationContext 接口的实现类做为bean的管理者,对于web应用,使用ConfigurableWebApplicationContext 接口的实现类做为bean的管理者。这两个接口,从结构上讲他们是继承关系,从应用上讲他们是平级关系,在不一样的领域为Spring提供强大的支撑。
Spring是一个优秀的框架,具备良好的结构设计和接口抽象,它的每个接口都是其功能具体到各个模块中的高度抽象,实际使用过程当中至关于把接口的各个实现类按照接口所提供的组织架构装配起来以提供完整的服务,能够说掌握了Spring的接口就至关于掌握了Spring的大部分功能。
ApplicationContext 的实现类众多,然而
上文中分析了 ApplicationContext 接口的各个功能,下面将分析 ApplicationContext 的实现类对上述接口的各个功能都是怎样实现的(PS. 限于篇幅,这里仅仅指出上述各个功能在实现类中什么位置经过什么方法实现,至于其具体实现过程,每个功能拿出来均可以单独写一篇文章了,这里不进行详述)。至于实现类又扩展了其余接口或者继承了其余父类,这些只是实现类为了扩展功能或者为了对实现上述接口提供便利而作的事情,对ApplicationContext接口抽象出来的功能没有影响或者没有太大帮助,所以略去。
以ClassPathXmlApplicationContext为例,其主要继承关系以下:
org.springframework.context.support.AbstractApplicationContext org.springframework.context.support.AbstractRefreshableApplicationContext org.springframework.context.support.AbstractRefreshableConfigApplicationContext org.springframework.context.support.AbstractXmlApplicationContext org.springframework.context.support.ClassPathXmlApplicationContext
而最顶层抽象类 AbstractApplicationContext 又实现了 ConfigurableApplicationContext 接口。
AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean
根据上文所述,这里略去其父类 DefaultResourceLoader 和接口 DisposableBean ,只关注接口 ConfigurableApplicationContext,回忆一下该的主要功能:
Configable, //可配置(该接口自己扩展的功能) Lifecycle, //生命周期可管理 Closeable,//可关闭(释放资源) EnvironmentCapable,//可配置Environment MessageSource, //可管理message实现国际化等功能 ApplicationEventPublisher, //可publish事件,调用Listener ResourcePatternResolver,//加载pattern指定的资源 ListableBeanFactory, HierarchicalBeanFactory,//管理Bean的生命周期,这个最重要,放最后说
而后回到最顶层抽象类 AbstractApplicationContext ,该抽象类能够说是 ClassPathXmlApplicationContext 继承结构中代码量最多的类,上述的大部分功能也都在该类中实现。该类采用模板方法模式,实现了上述功能的大部分逻辑,而后又抽出许多 protected方法(或 abstract 方法)供子类override 。
各功能的实现列举以下:
Configable:如setParent/setEnvironment等方法,由AbstractApplicationContext实现 。代码示例:
@Override public void setParent(ApplicationContext parent) { this.parent = parent; if (parent != null) { Environment parentEnvironment = parent.getEnvironment(); if (parentEnvironment instanceof ConfigurableEnvironment) { getEnvironment().merge((ConfigurableEnvironment) parentEnvironment); } } }
Lifecycle:AbstractApplicationContext拥有一个LifecycleProcessor实例,用于管理自身的生命周期,AbstractApplicationContext的Lifecycle方法如start、stop等由会代理给LifecycleProcessor进行处理,代码示例:
@Override public void start() { getLifecycleProcessor().start(); publishEvent(new ContextStartedEvent(this)); }
Closeable:由AbstractApplicationContext实现,用于关闭ApplicationContext销毁全部beans,此外若是注册有JVM shutdown hook,一样要将其移除 。代码示例:
@Override public void close() { synchronized (this.startupShutdownMonitor) { doClose(); if (this.shutdownHook != null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); }catch (IllegalStateException ex) { // ignore - VM is already shutting down } } } }
EnvironmentCapable:由AbstractApplicationContext实现,其持有一个ConfigurableEnvironment实例,用来实现EnvironmentCapable接口的getEnvironment方法 。代码示例:
@Override public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
MessageSource:AbstractApplicationContext持有一个MessageSource实例,将MessageSource接口的方法代理给该实例来完成 。代码示例:
@Override public String getMessage(String code, Object args[], String defaultMessage, Locale locale) { return getMessageSource().getMessage(code, args, defaultMessage, locale); }
ApplicationEventPublisher:由AbstractApplicationContext实现,若是存在父级ApplicationContext,则一样要将event发布给父级ApplicationContext。代码示例:
@Override public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); } }
ResourcePatternResolver:AbstractApplicationContext持有一个ResourcePatternResolver实例,该接口的方法代理给该实例完成 。代码示例:
@Override public Resource[] getResources(String locationPattern) throws IOException { return this.resourcePatternResolver.getResources(locationPattern); }
ListableBeanFactory, HierarchicalBeanFactory: AbstractApplicationContext 间接实现了这两个接口,然而却并无实现任何BeanFactory的任何功能。AbstractApplicationContext 拥有一个 ConfigurableListableBeanFactory实例,全部BeanFactory的功能都代理给该实例完成。代码示例:
@Override public Object getBean(String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); }
而AbstractApplicationContext 的 getBeanFactory() 方法是一个抽象方法,即由子类来提供这个BeanFactory。代码示例:
@Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
在 ClassPathXmlApplicationContext 的继承体系中,类AbstractRefreshableApplicationContext实现了这个 getBeanFactory()方法。这里getBeanFactory()方法会建立一个DefaultListableBeanFactory实例做为返回值。
本文以 Spring Framework 的 ApplicationContext 为中心,分析了 ApplicationContext 的机构体系和功能实现。接口 ApplicationContext 继承了众多接口,能够知足应用中“面向接口编程”的经常使用功能需求。抽象类 AbstractApplicationContext 实现了ApplicationContext 接口中简单不易变更的部分,而后经过“组合”将众多“容易变更”功能代理给它的一些成员变量来实现,最后再使用模板方法模式让子类为父类提供一些函数的支持或者设置替换父类的上述成员变量,从而实现了“对扩展开放,对修改封闭”的设计原则,为Spring Framework 提供了灵活性大可扩展性强的架构支撑。