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

转载 2013年11月13日 15:30:17

转自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. }  

  • 首先获取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. }  

  • 第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. }  

  • 第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. }  

  • 和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. }  

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

 

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


提取现成的ts流中的i帧文件

进入公司的新人培训第二个作业,看了几天的文档都没太搞懂es包的结构,网上的资源也比较少,多数是介绍ts流和pes包的。所以花费了好几天才完成。     这个作业是对第一个作业的继续,在上一次作业中成功...

Spring IOC源码详解之容器初始化

Spring IOC源码详解之容器初始化 上篇介绍了Spring IOC的大致体系类图,先来看一段简短的代码,使用IOC比较典型的代码 ClassPathResource...

Java for Web学习笔记(七三):国际化i18n(1)使用Spring框架MessageSource

一般性了解 我们在JSTL fmt[1]中已经接触过国际化i18n,本地化L10n。使用JSTL fmt(Internationalization and Formatting tag library...

spring学习笔记(16)趣谈spring 事件机制[2]:多监听器流水线式顺序处理

上一篇我们使用到的ApplicationListener是无序的,结合异步调度它能满足了我们的大部分应用场景,但现在我们来个另类的需求,我们来模拟一条作业调度流水线,它不能异步,必须按照先后次序执行不...

Java学习笔记(二)事件监听器

Java实现对组件事件(如单击、输入等)的监听和JavaScript类似,都是先添加Listener,再写触发函数,不同的是,Java实现监听前必须使用implements将各个接口添加到类内。   ...

spring源码学习笔记-初始化(二) PostProcessor

下面我们重点查看这个方法: protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFa...

spring源码学习笔记-初始化(四)-PostProcessor

转自http://www.sandzhang.com/blog/2011/04/05/spring-study-notes-initialization-4/ refresh()方法中在上篇看到...

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

转自http://www.sandzhang.com/blog/2011/04/08/spring-study-notes-initialization-6/ refresh()方法中在上篇看完...

spring源码学习笔记-初始化(二)-BeanFactory

转自http://www.sandzhang.com/blog/2011/04/02/spring-study-notes-initialization-2/ 上篇结束的地方简单介绍了一下ref...

spring源码学习笔记-初始化(一)-概览

转自http://www.sandzhang.com/blog/2011/03/30/spring-study-notes-initialization-1/ 版本:spring-framewo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:spring源码学习笔记-初始化(五)-MessageSource/事件监听器
举报原因:
原因补充:

(最多只允许输入30个字)