spring源码学习笔记-初始化(六)-完成及异常处理

转自http://www.sandzhang.com/blog/2011/04/08/spring-study-notes-initialization-6/

refresh()方法中在上篇看完了MessageSource及时间监听器等初始话处理,这篇继续往下看。

注:refresh()的代码就不再次列举了,请看spring源码中AbstractApplicationContext类。

一、finishBeanFactoryInitialization(beanFactory)这个方法将完成BeanFactory的初始化,主要做的事就是初始化除了之前处理过的特殊bean之外的所有单例bean,代码如下:

  1. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && 
  2.         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { 
  3.     beanFactory.setConversionService( 
  4.             beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); 
  5.   
  6. beanFactory.setTempClassLoader(null); 
  7. beanFactory.freezeConfiguration(); 
  8. beanFactory.preInstantiateSingletons(); 
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));
}
 
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();

  • 第1-5行判断如果定义了名为conversionService并且类型为ConversionService的bean,则把其设置为beanFactory的conversionService属性。这个主要是用来提供数据转化服务的
  • 销毁之前在prepareBeanFactory()中生成的临时ClassLoader
  • freezeConfiguration()的代码如下:
  1. this.configurationFrozen = true
  2. synchronized (this.beanDefinitionMap) { 
  3.     this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames); 
this.configurationFrozen = true;
synchronized (this.beanDefinitionMap) {
    this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}

  • 这个方法就是代表bean定义等配置已经可以缓存了,不会再有其他地方对其做修改了
  • 最后一行就是对所有非延迟加载的单例bean进行初始化了我们来看下这个方法的代码:

  1. if (this.logger.isInfoEnabled()) { 
  2.     this.logger.info("Pre-instantiating singletons in " + this); 
  3. synchronized (this.beanDefinitionMap) { 
  4.     for (String beanName : this.beanDefinitionNames) { 
  5.         RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 
  6.         if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 
  7.             if (isFactoryBean(beanName)) { 
  8.                 final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); 
  9.                 boolean isEagerInit; 
  10.                 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 
  11.                     isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 
  12.                         public Boolean run() { 
  13.                             return ((SmartFactoryBean) factory).isEagerInit(); 
  14.                         } 
  15.                     }, getAccessControlContext()); 
  16.                 } 
  17.                 else
  18.                     isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit();  
  19.                 } 
  20.                 if (isEagerInit) { 
  21.                     getBean(beanName); 
  22.                 } 
  23.             } 
  24.             else
  25.                 getBean(beanName); 
  26.             } 
  27.         } 
  28.     } 
if (this.logger.isInfoEnabled()) {
    this.logger.info("Pre-instantiating singletons in " + this);
}
synchronized (this.beanDefinitionMap) {
    for (String beanName : this.beanDefinitionNames) {
        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>() {
                        public Boolean run() {
                            return ((SmartFactoryBean) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                }
                else {
                    isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit(); 
                }
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
            else {
                getBean(beanName);
            }
        }
    }
}

  • 首先是一行info级别的日志,然后在对象beanDefinitionMap的同步下循环所有bean的name分别进行初始化
    首先获取bean定义信息对象bd,然后进行判断,这里只对非抽象bean(抽象bean是用于继承定义配置等信息的不可初始化)、单例、非延迟加载的bean进行处理
    判断如果是FactoryBean则进行下面的处理,如果不是直接调用getBean(beanName),这个方法调用会进行这个bean的初始化,关于这个方法还是放到BeanFactory的单独分析里面这里就不往里看了。
    对于FactoryBean的获取,要在beanname前加上一个&,然后会先判断是否是SmartFactoryBean并且渴望初始化(EagerInit),如果是才调用getBean(beanName),否则这个应该是在第一次调用工厂的getObject的时候才初始化
    注:对于这中间AccessController.doPrivileged的运用没有搞明白,留待以后分析,不知道为什么要在这里使用这个

二、最后的一个处理是finishRefresh()方法,代码如下:


  1. initLifecycleProcessor(); 
  2. getLifecycleProcessor().onRefresh(); 
  3. publishEvent(new ContextRefreshedEvent(this)); 
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
publishEvent(new ContextRefreshedEvent(this));

1.先看initLifecycleProcessor()方法的代码:

  1. ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 
  2. if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { 
  3.     this.lifecycleProcessor = 
  4.             beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); 
  5.     if (logger.isDebugEnabled()) { 
  6.         logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]"); 
  7.     } 
  8. else
  9.     DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); 
  10.     defaultProcessor.setBeanFactory(beanFactory); 
  11.     this.lifecycleProcessor = defaultProcessor; 
  12.     beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); 
  13.     if (logger.isDebugEnabled()) { 
  14.         logger.debug("Unable to locate LifecycleProcessor with name '"
  15.                 LIFECYCLE_PROCESSOR_BEAN_NAME + 
  16.                 "': using default [" + this.lifecycleProcessor + "]"); 
  17.     } 
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
    this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
    if (logger.isDebugEnabled()) {
        logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
    }
}
else {
    DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
    defaultProcessor.setBeanFactory(beanFactory);
    this.lifecycleProcessor = defaultProcessor;
    beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
    if (logger.isDebugEnabled()) {
        logger.debug("Unable to locate LifecycleProcessor with name '" +
                LIFECYCLE_PROCESSOR_BEAN_NAME +
                "': using default [" + this.lifecycleProcessor + "]");
    }
}

这个方法主要是用来初始化生命周期管理器LifecycleProcessor的

  • 如果用户定义了名为lifecycleProcessor类型为LifecycleProcessor的LocalBean,则赋值给当前ApplicationContext的lifecycleProcessor属性
  • 如果用户没有定义,则初始化默认的生命周期管理器DefaultLifecycleProcessor,注册单例bean,并赋值给lifecycleProcessor属性

2.initLifecycleProcessor()方法之后则是对生命周期管理器的触发,LifecycleProcessor有两个触发点onRefresh()和onClose(),当前正处于refresh所以调用其onRefresh()方法

3.调用publishEvent()方法发布ContextRefreshedEvent事件,publishEvent()的代码也很简单就不介绍了,就是调用当前上下文及parent的ApplicationEventMulticaster的multicastEvent()方法,这个放到分析事件处理模块时再去详细分析。

三、最后分析一下在整个try代码块中如果抛出异常的处理,可以看到分为了两个方法调用:

1.destroyBeans()代码很简单,就是调用BeanFactory的destroySingletons()方法销毁所有单例bean。还是暂不细看放到BeanFactory专项分析里去

2.cancelRefresh()这个方法代码看一下:


  1. synchronized (this.activeMonitor) { 
  2.     this.active = false
synchronized (this.activeMonitor) {
    this.active = false;
}

就是在同步下设置状态值而已,但是有个小细节,这个方法在AbstractRefreshableApplicationContext和GenericApplicationContext两个子类中进行了重写,但是也很简单,就是增加了一个beanFactory.setSerializationId(null)然后依旧调用上面super中的方法进行修改状态

关于ApplicationContext的基本初始化的过车这就分析完了,中间碰到了很多问题,也还有很多地方需要详细研究,下面列举备忘一下,后面挨个分析:

  1. bean定义的加载
  2. bean的初始化
  3. BeanFactory的一些核心方法
  4. BeanFactory和ApplictionContext的关系以及各自的类继承框架
  5. 扩展点BeanFactoryPostProcessor及BeanPostProcessor
  6. 事件监听器ApplicationListener
  7. 信息管理器MessageSource
  8. 属性编辑器PropertyEditor
  9. 生命周期管理器LifecycleProcessor
  10. 还有几个小细节例如LoadTimeWeaver、MergedBeanDefinitionPostProcessor、AccessController.doPrivileged
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值