1.导语
ApplicationContext(简称为AC)被我们称之为上下文,语文不好的我确实很难去想象它到底是什么,直到我翻开了它的源码实现。
2."上下文"的接口
-
AplicationContext
- EnvironmentCapable
-
ListableBeanFactory
- BeanFactory
-
HierarchicalBeanFactory
- BeanFactory
- ApplicationEventPublisher
- ResourcePatternResolver
- MessageSource
从上面的接口继承关系可以看出,AC接口实际上继承了7个基类接口,这七个接口也赋予了spring应用5种属性,但是这是残缺的属性,在类上也注释了一段话(Central interface to provide configuration for an application.This is read-only while the application is running, but may be reloaded if the implementation supports this.) “read-only”?没错,仔细看这些接口,都只有get方法。
3.关于“上下文”的理解
在语言学中,上下文指的是语境,在编程语言中则指的是程序"共享部分". 那么在AC中,包含了bean factory,环境,事件推送,资源解析,消息等组件,而这些组件都是我们构建spring应用时可以“共享”的部分,这才被称之为上下文的吧。
4.可配置的“上下文”
如果只实现AC接口,那么这个context只是可读的。英语还可以的我,一眼就看见了ConfigurableApplicationContext(简称为CAC接口)这个接口:
-
ConfigurabaleApplicationContext
- ApplicationContext
- Lifecycle
- Close
CAC接口如其名一样,直接继承了AC接口,并且为context提供了操作配置和添加了lifecycle(生命周期),Closeable(类型IO可以关闭操作)两个属性。简单说就是为我们的spring跑车添加了可操作的驾驶室。
(这里忽略了CAC接口的重要性,将在下一篇讲到。)
5.“上下文”的抽象实现和代理模式
-
AbstractApplicationContext
- DefaultSourceLaoder (e)
- ConfigurabaleApplicationContext (i)
因为涉及继承(extend)和实现(implements),在类,接口关系中(e)表示继承,(i)表示实现。
AbstractApplicationContext(简称AAC)类是“上下文”的第一个实现,实现CAC意味着要实现10个接口类,实现几十个接口方法,可想而知都在AAC中实现将把AAC类撑得无比臃肿,那么此时设计模式就开始发力了。
- 代理模式
- 抽象代理模式
/** ResourcePatternResolver used by this context. */
private ResourcePatternResolver resourcePatternResolver;
/** LifecycleProcessor for managing the lifecycle of beans within this context. */
@Nullable
private LifecycleProcessor lifecycleProcessor;
/** MessageSource we delegate our implementation of this interface to. */
@Nullable
private MessageSource messageSource;
/** Helper class used in event publishing. */
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
上面代码是AAC中的私有属性,我们可以将其称之为代理者,对于需要实现的Lifecyclye,SourceMessgae,ApplicationEventPublisher,ResourcePatternResolver等接口都将其委托给对应的代理者去实现,而AAC只调用代理者实现方法,这就是代理模式。如此妙用代理模式已经震惊我这个小码农,翻了很久也没找到BeanFactory, ListableBeanFactory,HierarchicalBeanFactory的代理者:
看,确实没有~~ 但是。。。
@Override
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name);
}
getBeanFactory() ??难道是抽象代理!!!
/**
* Subclasses must return their internal bean factory here. They should implement the
* lookup efficiently, so that it can be called repeatedly without a performance penalty.
* <p>Note: Subclasses should check whether the context is still active before
* returning the internal bean factory. The internal factory should generally be
* considered unavailable once the context has been closed.
* @return this application context's internal bean factory (never {@code null})
* @throws IllegalStateException if the context does not hold an internal bean factory yet
* (usually if {@link #refresh()} has never been called) or if the context has been
* closed already
* @see #refreshBeanFactory()
* @see #closeBeanFactory()
*/
@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
好吧,是在下没见识。最后这些核心的功能都被代理出去了,到此AC接口及其父类接口算是实现了,只剩下CAC接口中的方法了,而这些才是AAC接口真正做的事情。
6.结束语
到此我们知道CAC底层接口的搭建,也粗略的看了一下AAC中的实现方式,感觉没写什么,篇幅就很长了,就此打住,下一篇再写了。