博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring 启动之全过程 源码解析
阅读量:1986 次
发布时间:2019-04-27

本文共 16991 字,大约阅读时间需要 56 分钟。

 

主类代码

public class BeanLifeCycle {    public static void main(String[] args) {        System.out.println("现在开始初始化容器");        ApplicationContext factory = new ClassPathXmlApplicationContext("test/beans.xml");        System.out.println("容器初始化成功");        Person person = factory.getBean("person",Person.class);        System.out.println(person);               System.out.println("现在开始关闭容器!");                ((ClassPathXmlApplicationContext)factory).close();//registerShutdownHook();    }}

debug调试

方法栈

定位到AbstractApplicationContext类的refreash方法

@Override	public void refresh() throws BeansException, IllegalStateException {		synchronized (this.startupShutdownMonitor) {			// Prepare this context for refreshing.            //设置启动时间,设置context状态为active,初始化早期事件容器earlyApplicationEvents,调用校验validateRequiredProperties			prepareRefresh();            //创建BeanFactory实例new DefaultListableBeanFactory对象,并扫描xml解析所有节点为BeanDefintion 并注册到BeanFactory			// Tell the subclass to refresh the internal bean factory.			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            //配置ClassLoader,注册resolvable,注册ApplicationContextAwareProcessor,ApplicationListenerDetector,忽略一些Aware接口			// Prepare the bean factory for use in this context.			prepareBeanFactory(beanFactory);			try {             //空方法,当所有的xml已经被载入并且产生了对应的beanDefinition时,这个函数将会被调用,此时bean的实例都没有产生,在此处可以对beanDefinition的属性进行修改、抑或是注册特别的beanPostProcessor用于对实例化的bean做最终处理。这里函数留空是为了让用户能够子类化,然后在里面写入自己需要的修改,典型的模板设计模式				// Allows post-processing of the bean factory in context subclasses.				postProcessBeanFactory(beanFactory);    //从注册的BeanDefintion 列表中,根据接口类型 实例化所有 实现了BeanFactoryPostProcessor接口的类(通过getBean),并注册实例到BeanFactory中的属性列表中(可以对列表排序),同时会回调其postProcessBeanFactory方法,传入当前beanFactory对象				// Invoke factory processors registered as beans in the context.				invokeBeanFactoryPostProcessors(beanFactory);//从注册的BeanDefintion 列表中,根据接口类型实例化所有实现了BeanPostProcessor接口的类(通过getBean),并注册实例到BeanFactory的属性列表中(可以对列表排序)。(注意这里不会回调其实现的方法)				// Register bean processors that intercept bean creation.				registerBeanPostProcessors(beanFactory);                //注册实现了国际化MessageSource接口的实例(通过getBean),用于语言国际化				// Initialize message source for this context.				initMessageSource();                //实例化事件处理器ApplicationEventMulticaster(通过getBean),并注册到BeanFactory,Context.publish发布的所有事件都通过此处理器发布,如果Spring容器没有定义,则创建SimpleApplicationEventMulticaster作为applicationEventMulticaster。				// Initialize event multicaster for this context.				initApplicationEventMulticaster();                //在Context刷新时调用,这是空的模板方法,留给子类实现并执行想要的操作				// Initialize other special beans in specific context subclasses.				onRefresh();                //将AbstractApplicationContext中注册的Listener bean都添加到EventMulticaster中。注意listener好像是被ApplicationListenerDetector 后置方法postProcessAfterInitialization调用时注入到Context中的				// Check for listener beans and register them.				registerListeners();                //实例化剩余的单例(非懒加载)实例。				// Instantiate all remaining (non-lazy-init) singletons.				finishBeanFactoryInitialization(beanFactory);                //完成刷新,实例化生命周期LifecycleProcessor并注册到Context并调用onRefresh,发布ContextRefreshedEvent事件,将本Context注册到ListBeansView中				// Last step: publish corresponding event.				finishRefresh();			}			catch (BeansException ex) {				if (logger.isWarnEnabled()) {					logger.warn("Exception encountered during context initialization - " +							"cancelling refresh attempt: " + ex);				}                //清空缓存中的单例,清空bean之间的依赖关系,清空其他缓存资源				// Destroy already created singletons to avoid dangling resources.				destroyBeans();                				// Reset 'active' flag.                //设置当前context状态active=false				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();			}		}	}

 

具体说明

/**	 * Prepare this context for refreshing, setting its startup date and	 * active flag as well as performing any initialization of property sources.	 */	protected void prepareRefresh() {		this.startupDate = System.currentTimeMillis();		this.closed.set(false);		this.active.set(true);		if (logger.isInfoEnabled()) {			logger.info("Refreshing " + this);		}		// Initialize any placeholder property sources in the context environment		initPropertySources();		// Validate that all properties marked as required are resolvable		// see ConfigurablePropertyResolver#setRequiredProperties		getEnvironment().validateRequiredProperties();		// Allow for the collection of early ApplicationEvents,		// to be published once the multicaster is available...		this.earlyApplicationEvents = new LinkedHashSet
(); }
/**	 * Tell the subclass to refresh the internal bean factory.	 * @return the fresh BeanFactory instance	 * @see #refreshBeanFactory()	 * @see #getBeanFactory()	 */	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {		refreshBeanFactory();		ConfigurableListableBeanFactory beanFactory = getBeanFactory();		if (logger.isDebugEnabled()) {			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);		}		return beanFactory;	}
/**	 * Configure the factory's standard context characteristics,	 * such as the context's ClassLoader and post-processors.	 * @param beanFactory the BeanFactory to configure	 */	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.getBeanClassLoader()));		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));		// Configure the bean factory with context callbacks.		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);		beanFactory.ignoreDependencyInterface(ApplicationContextAware.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);		// Register early post-processor for detecting inner beans as ApplicationListeners.		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(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());		}	}
/**	 * Modify the application context's internal bean factory after its standard	 * initialization. All bean definitions will have been loaded, but no beans	 * will have been instantiated yet. This allows for registering special	 * BeanPostProcessors etc in certain ApplicationContext implementations.	 * @param beanFactory the bean factory used by the application context	 */	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {	}
/**	 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,	 * respecting explicit order if given.	 * 

Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

/**	 * Instantiate and invoke all registered BeanPostProcessor beans,	 * respecting explicit order if given.	 * 

Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }

/**	 * Initialize the MessageSource.	 * Use parent's if none defined in this context.	 */	protected void initMessageSource() {		ConfigurableListableBeanFactory beanFactory = getBeanFactory();		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {			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 + "]");			}		}	}
/**	 * Initialize the ApplicationEventMulticaster.	 * Uses SimpleApplicationEventMulticaster if none defined in the context.	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster	 */	protected void initApplicationEventMulticaster() {		ConfigurableListableBeanFactory beanFactory = getBeanFactory();		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {			this.applicationEventMulticaster =					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);			if (logger.isDebugEnabled()) {				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");			}		}		else {			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);			if (logger.isDebugEnabled()) {				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +						"': using default [" + this.applicationEventMulticaster + "]");			}		}	}
/**	 * Template method which can be overridden to add context-specific refresh work.	 * Called on initialization of special beans, before instantiation of singletons.	 * 

This implementation is empty. * @throws BeansException in case of errors * @see #refresh() */ protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }

/**	 * Add beans that implement ApplicationListener as listeners.	 * Doesn't affect other listeners, which can be added without being beans.	 */	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 listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... Set
earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
/**	 * 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));		}		// Register a default embedded value resolver if no bean post-processor		// (such as a PropertyPlaceholderConfigurer bean) registered any before:		// at this point, primarily for resolution in annotation attribute values.		if (!beanFactory.hasEmbeddedValueResolver()) {			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {				@Override				public String resolveStringValue(String strVal) {					return getEnvironment().resolvePlaceholders(strVal);				}			});		}		// 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();	}
/**	 * Finish the refresh of this context, invoking the LifecycleProcessor's	 * onRefresh() method and publishing the	 * {@link org.springframework.context.event.ContextRefreshedEvent}.	 */	protected void finishRefresh() {		// Initialize lifecycle processor for this context.		initLifecycleProcessor();		// Propagate refresh to lifecycle processor first.		getLifecycleProcessor().onRefresh();		// Publish the final event.		publishEvent(new ContextRefreshedEvent(this));		// Participate in LiveBeansView MBean, if active.		LiveBeansView.registerApplicationContext(this);	}
/**	 * Template method for destroying all beans that this context manages.	 * The default implementation destroy all cached singletons in this context,	 * invoking {@code DisposableBean.destroy()} and/or the specified	 * "destroy-method".	 * 

Can be overridden to add context-specific bean destruction steps * right before or right after standard singleton destruction, * while the context's BeanFactory is still active. * @see #getBeanFactory() * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons() */ protected void destroyBeans() { getBeanFactory().destroySingletons(); }

/**	 * Cancel this context's refresh attempt, resetting the {@code active} flag	 * after an exception got thrown.	 * @param ex the exception that led to the cancellation	 */	protected void cancelRefresh(BeansException ex) {		this.active.set(false);	}
/**	 * Reset Spring's common core caches, in particular the {@link ReflectionUtils},	 * {@link ResolvableType} and {@link CachedIntrospectionResults} caches.	 * @since 4.2	 * @see ReflectionUtils#clearCache()	 * @see ResolvableType#clearCache()	 * @see CachedIntrospectionResults#clearClassLoader(ClassLoader)	 */	protected void resetCommonCaches() {		ReflectionUtils.clearCache();		ResolvableType.clearCache();		CachedIntrospectionResults.clearClassLoader(getClassLoader());	}

 

转载地址:http://goyvf.baihongyu.com/

你可能感兴趣的文章
logAnalyzer日志管理系统配置实例
查看>>
网络监控如影随形
查看>>
HAProxy高可用配置视频教程
查看>>
图解RHEL6从安装光盘中进行yum安装
查看>>
iRedMail邮件系统配置简易视频安装教程
查看>>
Windows Server8下补丁分发配置与iSCSI配置
查看>>
常用网络流量采集技术分析
查看>>
LDAP实现企业异构平台的统一认证
查看>>
Linux系统病毒防治
查看>>
Linux安全应用之防垃圾邮件服务器的构建
查看>>
Linux下网络服务的安全设置
查看>>
从零开始安装Hadoop视频教程
查看>>
如何在MAC机器中实现移动设备WiFI上网(没有专门的无线路由器的情况)
查看>>
揭秘TPM安全芯片技术及加密应用
查看>>
实测Untangle - Linux下的安全网关
查看>>
2012年中国系统架构师大会 即将开幕
查看>>
IBM软件技术峰会归来
查看>>
CloudFoundry 云平台部署
查看>>
Snort企业部署实战
查看>>
我的博客创作之路
查看>>