标签:
容器启动过程总体流程
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();
// 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();
// 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;
}
}
}第一个方法是prepareRefresh(),我们来看看这个方法具体都做什么了再总结下这个方法
prepareRefresh() {
.= System.();
(.) {
.= ;
}
(.isInfoEnabled()) {
.info(+ );
}
// 初始化上下文环境,容器的一些信息这个时候加载了进来比如 文件路径信息
initPropertySources();
//查看标示为必填的属性信息是否都有了
getEnvironment().validateRequiredProperties();
}
prepareRefresh()只包含了两个方法,这两个方法加载了服务器的一些信息和判断必填项是否都完整。
第二个方法:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
ConfigurableListableBeanFactory () {ConfigurableListableBeanFactory beanFactory = getBeanFactory();(.isDebugEnabled()) { .debug(+ getDisplayName() + + beanFactory); } beanFactory; }
refreshBeanFactory()这个方法比较复杂,做了很多我们平时忽略的事情,让我们仔细查看一下。
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
//0-0 destroyBeans();
//0-1 closeBeanFactory();
}
try {//1
DefaultListableBeanFactory beanFactory = createBeanFactory();//设置容器系列号,org.springframework.web.context.WebApplicationContext:
beanFactory.setSerializationId(getId());
//2 customizeBeanFactory(beanFactory);
//3 loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}首先就是如果容器现在已经启动,而我们要新启动一个容器,那么首要的就是销毁以前的容器,具体过程如下
//0-0
destroyBeans();
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
public void destroySingletons() {
if (logger.isInfoEnabled()) {
logger.info("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}这一个步骤就是清空容器和容器中注册了的bean。
//0-1
closeBeanFactory();
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {//对象序列号置空
this.beanFactory.setSerializationId(null);//对象释放
this.beanFactory = null;
}
}新建容器对象 DefaultListableBeanFactory beanFactory = createBeanFactory();新建一个DefaultListableBeanFactory.注意在这里面有一个方法getInternalParentBeanFactory(),这个方法获得并设置了父容器。当然在spring启动的过程中这个父容器是空的。
protected DefaultListableBeanFactory createBeanFactory() {
//
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}步骤2主要是判断了一下三件事情
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//bean是否允许覆盖
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}//bean是否允许循环引用
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}//把java注解和spring标准注解都放到了容器里面来了
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
this.autowireCandidateResolver = autowireCandidateResolver;
}

步骤3要加载bean loadBeanDefinitions(beanFactory);我想这个过程应该是漫长而负责的。实现了该方法的类一共有三个1、XmlWebApplicationContext 2、AbstractXmlApplicationContext 3、AnnotationConfigWebApplicationContext.在项目启动的过程中XmlWebApplicationContext 真正的被执行。其余两个执行情况以后做研究。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1 给指定工厂创建一个阅读器.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//.配置一个带有上下文资源环境的bean 定义阅读器,
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//允许子类个性初始化阅读器,程序可以实现接口XmlWebApplicationContext实现该方法实现个性化定制。initBeanDefinitionReader(beanDefinitionReader);
//加载beanDefinations
loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader);方法要加载bean的信息。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1 给指定工厂创建一个阅读器.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//.配置一个带有上下文资源环境的bean 定义阅读器,
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//允许子类个性初始化阅读器,程序可以实现接口XmlWebApplicationContext实现该方法实现个性化定制。initBeanDefinitionReader(beanDefinitionReader);
//加载beanDefinations
loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader);方法要加载bean的信息。
标签:
原文地址:http://my.oschina.net/zjItLife/blog/527640