Spring源码探究 之 IOC容器的实质

IOC容器初始化时,创建所有单例的bean,今天深入探索IOC容器的实质:

IOC容器初始化即创建ClassPathXmlApplicationContext对象,如下:

ApplicationContext ioc = new ClassPathXmlApplicationContex("applicationContext.xml");

其内部的创建代码如下:

ClassPathXmlApplicationContext类中的构造方法

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

调用了本类的另一个构造器方法

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {

	super(parent);
	//设置本地参数
	setConfigLocations(configLocations);
	if (refresh) {
		//创建IOC容器
		refresh();
	}
}

创建IOC容器的方法在org.springframework.context.support.AbstractApplicationContext

@Override
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();


		//准备beanFactory
		// 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();


			//初始化beanFactory
			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);


			// Last step: publish corresponding event.
			finishRefresh();
		}


		catch (BeansException ex) {
			// Destroy already created singletons to avoid dangling resources.
			destroyBeans();


			// Reset 'active' flag.
			cancelRefresh(ex);


			// Propagate exception to caller.
			throw ex;
		}
	}
}

初始化beanFactory即调用本类的方法,如下:

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();
		
	//初始化所有的单实例bean
	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}	


至此初始化所有的单实例bean,调用org.springframework.beans.factory.support.DefaultListableBeanFactory的preInstantiateSingletons()方法

//创建所有的单实例bean
@Override
public void preInstantiateSingletons() throws BeansException {
	if (this.logger.isDebugEnabled()) {
		this.logger.debug("Pre-instantiating singletons in " + this);
	}
	List<String> beanNames;
	//获得所有beanName
	synchronized (this.beanDefinitionMap) {
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		beanNames = new ArrayList<String>(this.beanDefinitionNames);
	}
	//遍历所有beanName的集合
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
				boolean isEagerInit;
				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
						@Override
						public Boolean run() {
							return ((SmartFactoryBean<?>) factory).isEagerInit();
						}
					}, getAccessControlContext());
				}
				else {
					isEagerInit = (factory instanceof SmartFactoryBean &&
							((SmartFactoryBean<?>) factory).isEagerInit());
				}
				if (isEagerInit) {
					getBean(beanName);
				}
			}
			else {
				//从IOC容器中获取bean,如果没有这个bean,
				//就去创建一个bean,并返回,如果有就从容器中拿 
				getBean(beanName);
			}
		}
	}
}


从IOC容器中获取bean,即执行org.springframework.beans.factory.support.AbstractBeanFactory类中的getBean方法

@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
	
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}


@Override
public Object getBean(String name, Object... args) throws BeansException {
	return doGetBean(name, null, args, false);
}

所有的getbean方法皆调用了本类的doGetBean方法

protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
	...
	//根据beanName获得所有单例模式的bean
	Object sharedInstance = getSingleton(beanName);
	...

根据beanName获取所有单例模式的bean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

如下即是具体的方法代码

@Override
public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}
	
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//从这个类的singletonObjects属性中获取
	Object singletonObject = this.singletonObjects.get(beanName);
	...

而singtonObjects,此属性的定义如下:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);

我们发现这些单例的对象其实是保存在一个map中
这个所谓的IOC容器就是一个map,所有的单例都保存在这个map中


具体流程:
ioc容器一启动就调用初始化---->AbstractApplicationContext.refresh()---->初始化所有的单实例对象
---->AbstractApplicationContext.finishBeanFactoryInitialization()----->调用getBean初始化bean
---->所有的getbean又调用AbstractBeanFactory.doGetbean();---->调用doGetBean的getSingleton(beanName);
---->第一次ioc初始化烦hi的是null,第二去调用getBean通过这个方法就已经返回了
bean实例,调用的是DefaultSingletonBeanRegistry.getSingleton();
就是从singletonObjects里面拿出对应的bean。
singletonObjects是一个map,声明如下,
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
这就是我们保存所有单实例对象的地方,ioc容器。

猜你喜欢

转载自blog.csdn.net/OnlyLove_longshao/article/details/53560447