一、介紹
ClassPathXmlApplicationContext具有XmlBeanFactory的所有功能,自我感覺他就是XmlBeanFactory擴展。
二、代碼切入點
@Test
public void testApplicationContext(){
applicationContext = new ClassPathXmlApplicationContext("bean.xml");
User user = applicationContext.getBean("user", User.class);
user = applicationContext.getBean("user", User.class);
}
三、分步驟分析
- 這步驟主要就是保存路徑和分析路徑中的佔位符。重中之重就是refresh方法。
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
- 這個方法寫的真是行雲流水,讓看代碼的人能很快的梳理整個結構,我認爲這是spring最優雅的代碼之一
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 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();
}
}
}
- prepareRefresh該方法主要是做一些準備工作,比如一些自定的初始化和驗證
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();
……
}
- obtainFreshBeanFactory該方法就是獲取BeanFactory。
在開始的時候說ClassPathXmlApplicationContext具有XmlBeanFactory的所有功能,主要就是在這個方法中體現的。它相當於把XmlBeanFactory組合進去了
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//使用的就是DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);//定製beanfactory,這個算是進行擴展,而且子類也可以重寫這個方法,這就是spring開放式設計
loadBeanDefinitions(beanFactory);//在子類中實現
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
-
prepareBeanFactory該方法主要是加載classloader和註冊一些後置處理器,增加spel和屬性解析器等等
-
postProcessBeanFactory 該方法是個空實現,會提供你一個BeanFactory參數。
-
invokeBeanFactoryPostProcessors 執行beanFactory級別的後置處理器,這個最高級別的後置處理器
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanFactoryPostProcessor 這個類的功能,就是bean的定義已經加載好,還沒有初始化,這個時候你可以驗證bean的定義或者修改bean的定義。
- registerBeanPostProcessors 這個方法是註冊容器級的後置處理器:這個包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,一般稱它們的實現類爲“後處理器”
- initMessageSource: 國際化資源處理
- initApplicationEventMulticaster: spring的event進行事件監聽,ApplicationEventMulticaster會持有監聽器集合
- onRefresh:這是個空方法,子類可以進行重寫
- registerListeners:把監聽器註冊到ApplicationEventMulticaster上面
- finishBeanFactoryInitialization:把那些非懶加載的bean直接實例化
- finishRefresh:這個目前不知道用處
四、Sping bean生命週期
從上面的源碼分析,很容易能得到spring的生命週期
五、get Bean
這個是和XmlBeanFactory一模一樣。