欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring ClassPathXmlApplicationContext bean参数替换及init单例初始化

程序员文章站 2022-05-21 23:07:58
...

ClassPathXmlApplicationContext 的bean参数替换及init 单例的核心代码
是public abstract class AbstractApplicationContext的如下函数:

@Override
	public void refresh() throws BeansException, IllegalStateException {
		 
			// 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);
				
				StartupStep beanPostProcess = this.getApplicationStartup().start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);
				//TODO  beanFactory beanFactory.destroyBean(beanFactory);
				
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();
//
//				// 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();
				 
			}
		 
	}

xml里面的类似id=" s i m p l e . i d " c l a s s = " {simple.id}" class=" simple.id"class="{simple.class}" 被替换为properties里面simple.id=springSimpleJob
发生在:invokeBeanFactoryPostProcessors(beanFactory);

实际被调用代码为类PropertySourcesPlaceholderConfigurer的如下函数:

@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		if (this.propertySources == null) {
			this.propertySources = new MutablePropertySources();
			if (this.environment != null) {
				this.propertySources.addLast(
					new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
						@Override
						@Nullable
						public String getProperty(String key) {
							return this.source.getProperty(key);
						}
					}
				);
			}
			try {
				PropertySource<?> localPropertySource =
						new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
				if (this.localOverride) {
					this.propertySources.addFirst(localPropertySource);
				}
				else {
					this.propertySources.addLast(localPropertySource);
				}
			}
			catch (IOException ex) {
				throw new BeanInitializationException("Could not load properties", ex);
			}
		}

		processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
		this.appliedPropertySources = this.propertySources;
	}

调用stack如下:

PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(ConfigurableListableBeanFactory) line: 129	
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Collection<BeanFactoryPostProcessor>, ConfigurableListableBeanFactory) line: 325	
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>) line: 183	
		ClassPathXmlApplicationContext(AbstractApplicationContext).invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) line: 746	
		ClassPathXmlApplicationContext(AbstractApplicationContext).refresh() line: 564	
		ClassPathXmlApplicationContext.<init>(String[], boolean, ApplicationContext) line: 144	
		ClassPathXmlApplicationContext.<init>(String) line: 85	
		SpringMain.main(String[]) line: 125	
	Thread [Thread-0] (Running)	
	Daemon Thread [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:5181] (Running)	
	Thread [SessionTracker] (Running)	
	Thread [SyncThread:0] (Running)	
	Thread [ProcessThread(sid:0 cport:-1):] (Running)		

而单例的初始化为finishBeanFactoryInitialization(beanFactory);,在执行finishBeanFactoryInitialization(beanFactory)前所有bean只是保存为内存对象,不会初始化。