Spring源码解读――Spring容器初始化 2

2014-11-24 02:55:42 · 作者: · 浏览: 0

这篇博客是前一篇博客Spring源码解读――Spring容器初始化 1的延续,在看这篇博客之前,最后先看一下前一篇


接着我们继续看WebApplicationContext的refresh()方法

先看一下他的顺序图

\

\



< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">//AbstractApplicationContext XmlWebApplicationContext的父类 @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 准备容器的更新 prepareRefresh(); // 告诉子类刷新内部bean工厂 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 配置factory的标准容器特征,包括classloader和postprocessor等 prepareBeanFactory(beanFactory); try { // 修改应用程序上下文的内部bean工厂标准后初始化。所有bean定义将被加载,但没有实例化bean。这允许在某些ApplicationContext实现类注册特殊BeanPostProcessors postProcessBeanFactory(beanFactory); // 实例化所有注册到BeanFactoryPostProcessor的bean,如果有次序,就按照次序实例化,必须在单例实例化之前 invokeBeanFactoryPostProcessors(beanFactory); // 实例化并调用所有注册BeanPostProcessor的bean,如果有次序,就按照次序实例化。 必须在 application bean的实例化之前调用。 registerBeanPostProcessors(beanFactory); // 实例化MessageSource() initMessageSource(); // 实例化ApplicationEventMulticaster initApplicationEventMulticaster(); // 实例化容器中特殊的类 onRefresh(); // 注册实现ApplicationListener的listener registerListeners(); // 完成容器的beanFactory的实例化,初始化所有剩余单例bean finishBeanFactoryInitialization(beanFactory); //调用LifecycleProcessor的onRefresh()以及发布 org.springframework.context.event.ContextRefreshedEvent。 finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } } }


我们再看一下ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();里面的操作

//AbstractApplicationContext
/**
	 * Tell the subclass to refresh the internal bean factory.
	 * @return the fresh BeanFactory instance
	 * @see #refreshBeanFactory()
	 * @see #getBeanFactory()
	 */
	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();    //创建一个DefaultListableBeanFactory,并加载类,实例化为对应的BeanDefinition
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();   //取得该DefaultListableBeanFactory,后面返回
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

我们在看一下refreshBeanFactory()


//AbstractRefreshableApplicationContext
/**
	 * This implementation performs an actual refresh of this context's underlying
	 * bean factory, shutting down the previous bean factory (if any) and
	 * initializing a fresh bean factory for the next phase of the context's lifecycle.
	 */
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();  //这里创建了一个DefaultListableBeanFactory,供后面实例化bean
			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);
		}
	}

我们在进入看loadBeanDefinitions()

//XmlWebApplicationContext
/**
	 * Loads the bean definitions via an XmlBeanDefinitionReader.
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// 这里为beanDefinitionReader配置容器的属性
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));


		initBeanDefinitionReader(beanDefinitionReader);     //这个方法其实是空的,留给以后subclass去实现
		loadBeanDefinitions(beanDefinitionReader);         //这里开始加载BeanDefinition了
	}

我们再进入loadBeanDefinitions()

//XmlWebApplicationContext
/**
	 * Load the bean definitions with the given XmlBeanDefinitionReader.
	 * 

The lifecycle of the bean factory is handled by the refreshBeanFactory method; * therefore this method is just supposed to load and/or register bean definitions. *

Delegates to a ResourcePatternResolver for resolving location patterns * into Resource instances. * @throws java.io.IOException if the required XML document isn't found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources * @see #getResourcePatternResolver */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { String[] configLocations = getConfigLocations(); //这里开始读取配置文件了,就是我们之前的applicationContext.xml的配置文件了 if (configLocations != null) { for (String configLocation : configLocations) { reader.loadBeanDefinitions(configLocation); //这里就开始加载配置文件中的bean了,实例化成beandefinition } } }


reader.loadBeanDefinitions(configLocation)

//AbstractBeanDefinitionReader
public int loadBeanDefinitions(String location, Set
  
    actualResources) throws BeanDefinitionStoreException {
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
		}

		if (resourceLoader instanceof ResourcePatternResolver) {
			// Resource pattern matching available.
			try {
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int loadCount = loadBeanDefinitions(resources); //这里就是加载了,返回加载类的数目
				if (actualResources != null) {
					for (Resource resource : resources) {
						actualResources.add(resource);
					}
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
				}
				return loadCount;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// Can only load single resources by absolute URL.
			Resource resource = resourceLoader.getResource(location);
			int loadCount = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
			}
			return loadCount;
		}
	}
  

接着回到refresh()方法中的prepareBeanFactory()

//AbstractApplicationContext
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(EnvironmentAware.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);

		// 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());
		}
	}
这里都是为beanFactory(也就是DefaultListableBeanFactory)设置一些属性


接着我们再看refresh()中的invokeBeanFactoryPostProcessors()

\

他最后交给DefaultListableBeanFactory去实例话那些注册到BeanFactoryPostProcessor的那些类


//DefaultListableBeanFactory
private String[] doGetBeanNamesForType(Class
   type, boolean includeNonSingletons, boolean allowEagerInit) {
		List
  
    result = new ArrayList
   
    (); // 获得之前加载的类名 String[] beanDefinitionNames = getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) {//遍历之前加载的全部类,并从中找出注册到BeanFactoryPostProcessor的那些类,把他们加入到result,为下面实例化 // Only consider bean as eligible if the bean name // is not defined as alias for some other bean. if (!isAlias(beanName)) { try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Only check bean definition if it is complete. if (!mbd.isAbstract() && (allowEagerInit || ((mbd.hasBeanClass() || !mbd.isLazyInit() || this.allowEagerClassLoading)) && !requiresEagerInitForType(mbd.getFactoryBeanName()))) { // In case of FactoryBean, match object created by FactoryBean. boolean isFactoryBean = isFactoryBean(beanName, mbd); boolean matchFound = (allowEagerInit || !isFactoryBean || containsSingleton(beanName)) && (includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type); if (!matchFound && isFactoryBean) { // In case of FactoryBean, try to match FactoryBean instance itself next. beanName = FACTORY_BEAN_PREFIX + beanName; matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type); } if (matchFound) { result.add(beanName); } } } catch (CannotLoadBeanClassException ex) { if (allowEagerInit) { throw ex; } // Probably contains a placeholder: let's ignore it for type matching purposes. if (this.logger.isDebugEnabled()) { this.logger.debug("Ignoring bean class loading failure for bean '" + beanName + "'", ex); } onSuppressedException(ex); } catch (BeanDefinitionStoreException ex) { if (allowEagerInit) { throw ex; } // Probably contains a placeholder: let's ignore it for type matching purposes. if (this.logger.isDebugEnabled()) { this.logger.debug("Ignoring unresolvable metadata in bean definition '" + beanName + "'", ex); } onSuppressedException(ex); } } }
   
  

这里,后面的refresh()的registerBeanPostProcessors(beanFactory)实例化过程是和之前的invokeBeanFactoryPostProcessors()一样的。


我们再来看refresh()的initMessageSource()

//AbstractApplicationContext
protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {   //如果配置文件applicationContext.xml有配置messageSource,就根据配置文件实例化
                        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

这里就是根据我们在配置文件applicationContext.xml中的时候有messagesource的配置,有的话就是实例化,没有的话就实例化一个DelegatingMessageSource,再把他设置到容器,在把他注册到单例集合中


接着,refresh()的initApplicationEventMulticaster()就是初始化ApplicationEventMulticaster。如果我们自己没有配置自定义的ApplicationEventMulticaster那就使用SimpleApplicationEventMulticaster


\

实例化思路还是和实例化messageSource差不多,都是从配置文件优先,如果没有明确配置就用默认的


接着,我们再来看refresh()的registerListener(),他就是先注册静态的容器本来级就应该有的类,然后在从我们之前加载的类中筛选listener,帅选实例化过程和之前的invokeBeanFactoryPostProcessors()实例化过程是一样的,记着在把listener加入到上面实例化的ApplicationEventMulticaster(它其实就是一个listener容器)中

//AbstractApplicationContext
protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener
   listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String lisName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(lisName);
		}
	}

接着就是refresh()的finishBeanFactoryInitialization()

//AbstractApplicationContext	
/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	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);

		// 允许缓存所有将不会被修改或进一步后期处理的bean定义元数据
		beanFactory.freezeConfiguration();

		// 实例化所有剩下的单例bean
		beanFactory.preInstantiateSingletons();
	}


再接着,refresh()的finishRefresh()
\


最后回到上篇博客中的initWebApplicationContext中

//ClassLoader
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
			throw new IllegalStateException(
					"Cannot initialize context because there is already a root application context present - " +
					"check whether you have multiple ContextLoader* definitions in your web.xml!");
		}

		Log logger = LogFactory.getLog(ContextLoader.class);
		servletContext.log("Initializing Spring root WebApplicationContext");
		if (logger.isInfoEnabled()) {
			logger.info("Root WebApplicationContext: initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			// Store context in local instance variable, to guarantee that
			// it is available on ServletContext shutdown.
			if (this.context == null) {
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent ->
						// determine parent for root web application context, if any.
						ApplicationContext parent = loadParentContext(servletContext);
						cwac.setParent(parent);
					}
					configureAndRefreshWebApplicationContext(cwac, servletContext);
				}
			}
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
			if (ccl == ContextLoader.class.getClassLoader()) {
				currentContext = this.context;
			}
			else if (ccl != null) {
				currentContextPerThread.put(ccl, this.context);
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
			}
			if (logger.isInfoEnabled()) {
				long elapsedTime = System.currentTimeMillis() - startTime;
				logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
			}

			return this.context;
		}
		catch (RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
			throw ex;
		}
		catch (Error err) {
			logger.error("Context initialization failed", err);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
			throw err;
		}
	}

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); 将容器设置为ServletContext的属性,之前我们已经这是了ServletContext作为WebApplicationContext的属性,于是,两者相关联,可以通过ServletContext.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)获得容器


自此,Spring容器创建完毕