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方法()

相关文章
相关标签/搜索