Spring中還提供了另一個接口ApplicationContext,繼承了BeanFactory,且包含BeanFactory的所有功能,並額外提供了一些其他的功能。比如國際化支持、事件機制、AOP支持等等。
通過ApplicationContext加載xml文件
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
}
進入構造器後主要有兩個邏輯
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);//設置配置路徑並支持多個配置文件
if (refresh) {
refresh();
}
}
在setConfigLocations中對路徑做了解析,比如${var}這樣的,會從環境變量中取到var的變量進行替換,而refresh中基本上包含了ApplicationContext的全部功能。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 刷新上下文環境,可通過重寫initPropertySource設置環境變量
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 初始化BeanFactory並進行xml文件讀取
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 對BeanFactory進行各種功能填充
prepareBeanFactory(beanFactory);
try {
// 空實現,可有子類實現,提供擴展能力
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 激活各種BeanFactoryPostProcessors處理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 註冊BeanPostProcessors處理器
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 國際化支持,初始化MessageSource
// Initialize message source for this context.
initMessageSource();
// 初始化事件廣播器,用於通知事件Listener
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 空實現,由子類實現
// Initialize other special beans in specific context subclasses.
onRefresh();
// 查找所有註冊的Listener,註冊到廣播器中
// Check for listener beans and register them.
registerListeners();
// 初始化生下的單實例(非惰性)
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 完成刷新過程,並觸發ContextRefreshEvent事件通知,通知生命週期處理器刷新過程
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
在refresh中邏輯還是很多的,根據代碼塊裏添加了中文註釋的地方逐步解釋
在prepareRefresh中是做環境的準備的,環境變量的初始化以及系統屬性的驗證,可以通過實現initPropertySource方法進行環境變量的賦值操作等
protected void prepareRefresh() {
// Initialize any placeholder property sources in the context environment.
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
}
接下來就是加載BeanFactory了,前面已經知道默認是使用XmlBeanDefinitionReader來讀取xml的
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
實例化DefaultListableBeanFactory,XmlBeanFactory就是繼承DefaultListableBeanFactory的;
在customizeBeanFactory中對BeanFactory進行了定製,設置是否允許覆蓋同名對象以及是否允許循環依賴,並設置支持註解的解析器 QualifierAnnotaionAutowireCandidateResolver
在loadBeanDefinitions中就是比較熟悉的了,指定XmlBeanDefinitionReader爲解析器,開始執行xml的解析了。
回到前面主流程中,接下來是對prepareBeanFacctory進行功能的填充
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
// 設置表達式語言的解析器,提供對SPEL語言的支持
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 增加屬性編輯器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 在bean初始化後,對實現Aware接口的實例提供一些資源
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略依賴
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 註冊依賴
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
在setBeanExproeeionResolver中設置了SPEL支持的解析器,比如可以通過#{var}這種方式取值,在bean進行屬性填充的時候,會通過這個解析器完成解析
在addPropertyEditorRegistrar中增加了屬性註冊編輯器,在ResourceEditorRegistrar中的registerCustomEditors中註冊了一系列常用類型的屬性編輯器;而ResourceEditorRegistrar是通過在AbstractBeanFactory中開始調用的,如下代碼
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
registerCustomEditors(bw);
}
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport =
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
if (!this.propertyEditorRegistrars.isEmpty()) {
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
try {
// 遍歷屬性編輯器註冊自定義編輯器
registrar.registerCustomEditors(registry);
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
"] failed because it tried to obtain currently created bean '" +
ex.getBeanName() + "': " + ex.getMessage());
}
onSuppressedException(ex);
continue;
}
}
throw ex;
}
}
}
if (!this.customEditors.isEmpty()) {
this.customEditors.forEach((requiredType, editorClass) ->
registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
}
}
接下來是addBeanPostProcessor,類ApplicationContextAwareProcessor實現了BeanPostProcessor接口,即會在bean實例化時候調用的,在postProcessBeforeInitialization中的invokeAwareInterfaces中,使實現了Aware接口的bean在被初始化之後可以取得一些資源
回到主流程,在功能填充後,即激活BeanFactoryPostProcessor,這個接口和BeanPostProcessor類似, BeanFactoryPostProcessor作用域範圍是容器級的,允許在容器實際實例化任何其他的bean之前讀取配置元數據。典型的應用是PropertyPlaceholderConfigure,在實例化bean之前會將 ${}格式進行變量替換。
註冊BeanPostProcessor, 按照排序順序進行註冊,且重複註冊情況會先移除在重新註冊,保證beanPostProcessor的唯一性,在bean實例化階段進行調用
在初始化消息 initMessageSource中,首先會查找已經定義的messageSource的bean,如果沒有則使用默認的DelegationMessageSource並註冊到beanFactory中
初始化事件廣播器,和初始化消息差不多,去查找applicationEventMulticater的bean,否則使用默認的SimpleApplicationEventMulticater,在multicasstEvent中會遍歷event的listener進行通知,觀察者模式的典型應用。
初始化廣播器後則是註冊所有listener,來接收廣播器的通知,即所有實現了ApplicationListener的bean
對於單例的bean(非lazy的),在ApplicationContext中會默認初始化,在preInstantiateSingletons中對單例的且非lazy的bean進行加載,即調用getBean方法。
在finishrefresh中,開始生命週期,通過實現Lifecycle接口,可以在生命週期開始時加載start方法,在最後會推送ContextRefreshEvent事件通知