Spring 源碼閱讀-ClassPathXmlApplicationContext

#Spring 源碼閱讀(二) ##一. 測試代碼spring

public class Client {
public  static void main(String[] args){

    ApplicationContext context =new ClassPathXmlApplicationContext ("/spring/spring-mvc.xml");
    People people=(People) context.getBean("people");
    people.setAge(12);
    people.setName("Lily");
    people.setSex("girl");
    System.out.println(people.toString());
}

}數組

輸出結果:People name:Lily sex:girl age:12spring-mvc

##二. 分析併發

1.首先跳進 AbstractApplicationContextmvc

static {	
	ContextClosedEvent.class.getName();
}

2.再進入 ClassPathXmlApplicationContextide

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	this(new String[] {configLocation}, true, null);
}

3.繼續往下post

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {
	
	super(parent);
	setConfigLocations(configLocations);
	if (refresh) {
		refresh();
	}
}

4.super(parent)方法最終轉到AbstractApplicationContext中執行測試

//建立一個新的AbstractApplicationContext
public AbstractApplicationContext(ApplicationContext parent) {
	this();
	setParent(parent);
}

5.接着執行AbstractRefreshableConfigApplicationContext中的setConfigLocations(configLocations)方法ui

//設置configLocations字符數組
	public void setConfigLocations(String... locations) {
	if (locations != null) {
		Assert.noNullElements(locations, "Config locations must not be null");
		this.configLocations = new String[locations.length];
		for (int i = 0; i < locations.length; i++) {
			this.configLocations[i] = resolvePath(locations[i]).trim();
		}
	}
	else {
		this.configLocations = null;
	}
}

6.再執行AbstractApplicationContext中的refresh()方法this

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// 初始化準備,分析見下
		prepareRefresh();
		// 建立beanFactory同時加載配置文件.xml中的beanDefinition,分析見下
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// 爲上下文使用準備好bean工廠,給beanFactory註冊一些標準組建,如ClassLoader,StandardEnvironment,BeanProcess  分析見下
		prepareBeanFactory(beanFactory);
		try {
			// //爲容器的某些子類指定特殊的BeanPost事件處理器				postProcessBeanFactory(beanFactory);
			// 調用全部BeanFactoryProcessor的postProcessBeanFactory()方法				invokeBeanFactoryPostProcessors(beanFactory);
			// 註冊BeanPostProcessor,BeanPostProcessor做用是用於攔截Bean的建立.
			registerBeanPostProcessors(beanFactory);
			// 初始化MessageSource,主要用做I18N本地化的內容
			initMessageSource();
			// 初始化事件廣播ApplicationEventMulticaster,使用觀察者模式,對註冊的ApplicationEvent時間進行捕捉 
			initApplicationEventMulticaster();
			// 初始化特殊bean的方法 						onRefresh();
			// 將全部ApplicationEventListener註冊到ApplicationEventMulticaster中
			registerListeners();
			// 初始化全部不爲lazy-init的bean,singleton實例,分析見下  
			finishBeanFactoryInitialization(beanFactory);
			// 初始化容器的生命週期事件處理器,併發布容器的生命週期事件lifecycle的bean並啓動(例如quartz的定時器等,分析見下
			finishRefresh();
		}

		catch (BeansException ex) {
			logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
			destroyBeans();
			cancelRefresh(ex);
			throw ex;
		}
	}
}

7.調用AbstractApplicationContext中的prepareRefresh()方法

protected void prepareRefresh() {
	this.startupDate = System.currentTimeMillis();
	//設置當前context是當前活躍的
	this.active.set(true);

	if (logger.isInfoEnabled()) {
		logger.info("Refreshing " + this);
	}

	// 初始化佔位符在上下文環境中,默認是不進行操做
	initPropertySources();

	// 驗證全部元素是符合要求的
	// see ConfigurablePropertyResolver#setRequiredProperties
	getEnvironment().validateRequiredProperties();
}

8.調用AbstractApplicationContext中的obtainFreshBeanFactory()方法

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (logger.isDebugEnabled()) {
		logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
	}
	return beanFactory;
}

8.1 調用AbstractRefreshableApplicationContext中的refreshBeanFactory方法

@Override
protected final void refreshBeanFactory() throws BeansException {
	//是否已經包含BeanFactory
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		customizeBeanFactory(beanFactory);
		//加載XML,分析見下
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			this.beanFactory = beanFactory;
		}
	}
}

8.1.1調用AbstractXmlApplicationContext中的loadBeanDefinitions(beanFactory)方法

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// 建立新的XmlBeanDefinitionReader
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// Configure the bean definition reader with this context's
	// resource loading environment.
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	//解析配置文件中的beanDefinition
	initBeanDefinitionReader(beanDefinitionReader);
	loadBeanDefinitions(beanDefinitionReader);
}

9.調用AbstractApplicationContext中的finishBeanFactoryInitialization()方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// Initialize conversion service for this context.
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// Stop using the temporary ClassLoader for type matching.
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes.
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

10.context.getBean("people")

跳進AbstractBeanFactory中的doGetBean方法()

相關文章
相關標籤/搜索