spring源码学习笔记-初始化(五)-MessageSource/事件监听器

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

refresh()方法中在上篇看完了对PostProcessors的处理,这篇继续往下看。

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

一、initMessageSource(),这个方法是对spring的MessageSource初始化,代码如下:


  1. ConfigurableListableBeanFactory beanFactory = getBeanFactory();  
  2. if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {  
  3.     //第1部分   
  4. }  
  5. else {  
  6.     //第2部分   
  7. }  
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
    //第1部分
}
else {
    //第2部分
}

  • 首先获取beanFactory对象,然后判断是否定义了名为messageSource的localbean,如果有则执行第1部分,否则执行第2部分,分别来看两部分代码 
    注:localbean实际上就是指查找的时候不会去parent查找这个bean,只从当前beanfactory去查找,很多地方有这个就不一一注明了

第1部分:


  1. this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);  
  2. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {  
  3.     HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;  
  4.     if (hms.getParentMessageSource() == null) {  
  5.         hms.setParentMessageSource(getInternalParentMessageSource());  
  6.     }  
  7. }  
  8. if (logger.isDebugEnabled()) {  
  9.     logger.debug("Using MessageSource [" + this.messageSource + "]");  
  10. }  
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
    HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
    if (hms.getParentMessageSource() == null) {
        hms.setParentMessageSource(getInternalParentMessageSource());
    }
}
if (logger.isDebugEnabled()) {
    logger.debug("Using MessageSource [" + this.messageSource + "]");
}

  • 第1行获取名为messageSource的bean赋值给当前ApplicationContext对象的messageSource属性
  • 第2行判断如果当前ApplicationContext的parent不为null;并且messageSource对象继承了HierarchicalMessageSource接口则进行如下处理:
        进行判断如果messageSource的parentMessageSource为空,则设置为getInternalParentMessageSource()方法的返回值。getInternalParentMessageSource()方法的代码也很简单
        (getParent() instanceof AbstractApplicationContext) ? ((AbstractApplicationContext) getParent()).messageSource : getParent()
        如果当前ApplicationContext的parent对象是AbstractApplicationContext或其子类类型则返回它的messageSource,否则直接返回其parent对象
  • 最后是打印一行debug级别日志表示当前应用的messageSource

 

第2部分:

  1. DelegatingMessageSource dms = new DelegatingMessageSource();  
  2. dms.setParentMessageSource(getInternalParentMessageSource());  
  3. this.messageSource = dms;  
  4. beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);  
  5. if (logger.isDebugEnabled()) {  
  6.     logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +  
  7.             "': using default [" + this.messageSource + "]");  
  8. }  
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 + "]");
}

  • 第1行创建一个DelegatingMessageSource对象dms
  • 第2行类似上面,设置dms的parentMessageSource为getInternalParentMessageSource()返回值
  • 第3行设置当前ApplicationContext的messageSource属性为dms
  • 第4行把这个对象注册一个名为messageSource的单例bean
  • 打印一行debut日志表示无用户定义messageSource,使用默认
二、紧接着处理完messageSource的初始化后下一行代码:initApplicationEventMulticaster(),主要是对spring的事件监听器的管理器的初始话,代码如下:

  1. ConfigurableListableBeanFactory beanFactory = getBeanFactory();  
  2. if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {  
  3.     this.applicationEventMulticaster =  
  4.             beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);  
  5.     if (logger.isDebugEnabled()) {  
  6.         logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");  
  7.     }  
  8. }  
  9. else {  
  10.     this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);  
  11.     beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);  
  12.     if (logger.isDebugEnabled()) {  
  13.         logger.debug("Unable to locate ApplicationEventMulticaster with name '" +  
  14.                 APPLICATION_EVENT_MULTICASTER_BEAN_NAME +  
  15.                 "': using default [" + this.applicationEventMulticaster + "]");  
  16.     }  
  17. }  
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 + "]");
    }
}

  • 和messageSource的处理类似,首先取得beanFactory对象,
  • 判断如果用户主动定义了applicationEventMulticaster的bean,则把这个bean设置给applicationEventMulticaster属性
  • 如果没有则初始话一个默认的SimpleApplicationEventMulticaster,注册bean并赋值给对应属性
  • 不同情况分别打印不同的日志,源代码中的日志打印最好也稍微注意一下有个印象,这样在看spring的日志时会更清晰

 

三、接下来是一个模板方法onRefresh(),第一篇中提到过这个是在处理messageSource、applicationEventMulticaster等特殊bean后,普通单例bean没初始话之前,为ApplicationContext子类提供扩展去处理一些类似的特殊bean。

    举个例子AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext中都有一个themeSource,这个就要放在这个方法里去初始化。这个themeSource是spring的主题功能,可以实现根据不同主题加载不同资源文件等功能。

 

四、上面处理了事件监听器的管理器初始化,现在开始做时间监听器的注册:registerListeners(),这个方法的代码如下:


  1. for (ApplicationListener listener : getApplicationListeners()) {  
  2.     getApplicationEventMulticaster().addApplicationListener(listener);  
  3. }  
  4.    
  5. String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.classtruefalse);  
  6. for (String lisName : listenerBeanNames) {  
  7.     getApplicationEventMulticaster().addApplicationListenerBean(lisName);  
  8. }  
for (ApplicationListener listener : getApplicationListeners()) {
    getApplicationEventMulticaster().addApplicationListener(listener);
}
 
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
    getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}

  • 上面3行是处理当前ApplicationContext中的静态特殊监听器集合,循环调用applicationEventMulticaster的addApplicationListener()方法注册到applicationEventMulticaster中
  • 后面的一部分首先取出所有类型为ApplicationListener的bean的name集合,然后循环调用applicationEventMulticaster的addApplicationListenerBean()方法注册到applicationEventMulticaster中
  • 注意上面两个注册方法的不同,分别会注册到applicationEventMulticaster.defaultRetriever的不同集合中

 

本篇分别看到了messageSource、applicationEventMulticaster和applicationListener以及中间提到的主题themeSource的初始化,这里主要介绍初始话,所以后续再对spring的这几个功能模块做分别详细的分析。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值