initMessageSource方法
初始化消息。中文环境显示中文,英文环境显示英文。主要在SpringMVC中,通过国际化代码,这是个重点。
protected void initMessageSource() {
// 获取bean工厂,一般是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 首先判断是否已有xml文件定义了id为messageSource的bean对象
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 如果有,则从BeanFactory中获取这个对象
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
// 当父类bean工厂不为空,并且这个bean对象是HierarchicalMessageSource类型
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
// 类型强制转换,转换为HierarchicalMessageSource的类型
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
// 判断父类的messageSource是否为空,如果等于空,则设置父类的messageSource
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
// 如果没有xml文件定义信息源对象,新建DelegatingMessageSource类作为messageSource的bean
DelegatingMessageSource dms = new DelegatingMessageSource();
// 给这个DelegatingMessageSource添加父类消息源
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
// 将这个messageSource实例注册到bean工厂中
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
判断是否包含一个messageSource的bean对象(无论xm或者注解),如果有,那么获取messageSource这个类传进beanFactory里面去。如果没有,则创建一个默认的delegeatingMessageSource,然后将创建出来的对象注册到我们当前工厂里面去了。
initApplicationEventMulticaster方法
初始化事件监听多路广播器,用了观察者模式。
spring在正常的观察者模式中加入了一个事件驱动。以前都是被观察者调用方法,由方法触发对应的操作。这里把具体操作转换为一个事件。
执行过程:
- 事件源发布不同的事件。
- 当发布事件之后会调用多播器的方法来进行广播操作,由多播器去触发具体的监听器
- 监听器接收到具体的事件后,可以验证匹配是否能出来当前事件,如果不行,则不做任何操作。
实际代码处理:
- 提前准备好N个事件
- 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
- 准备好一系列监听器
- 向多播器注册已有的监听器
- 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作
protected void initApplicationEventMulticaster() {
// 获取当前bean工厂,一般是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断容器中是否存在bdName为applicationEventMulticaster的bd,也就是说自定义的事件监听多路广播器,必须实现ApplicationEventMulticaster接口
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 如果有,则从bean工厂得到这个bean对象
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
// 如果没有,则默认采用SimpleApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
这里和上面哪个方法类似,默认创建了一个多播器SimpleApplicationEventMulticaster,
现在做向多播器注册已有的监听器。
下面方法了,registerListeners()
registerListeners()方法
向多播器注册已有的监听器。
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!
// 从容器中获取所有实现了ApplicationListener接口的bd的bdName
// 放入ApplicationListenerBeans集合中
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
// getApplicationEventMulticaster().addApplicationListener(this.getBean(listenerBeanName,ApplicationListener.class));
}
// Publish early application events now that we finally have a multicaster...
// 此处先发布早期的监听器集合
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
这就是在多播器中加入监听器。
从bean工厂查看、应用程序是否有监听器,第三个,将发布早期的监听器集合,在prepareRefresh中,加入的。
放的一个是对象,一个放的名字(遍历名字再实例化)。
已经完成了第四步了,“准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作这个事情” 在下面完成。
这个第五步实际上是在finishRefresh里面实现的。有个方法pulishEvent。
总结
执行过程:
- 事件源发布不同的事件。
- 当发布事件之后会调用多播器的方法来进行广播操作,由多播器去触发具体的监听器
- 监听器接收到具体的事件后,可以验证匹配是否能出来当前事件,如果不行,则不做任何操作。
实际代码处理:
- 提前准备好N个事件
- 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
- 准备好一系列监听器
- 向多播器注册已有的监听器
- 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作
下面就到了最重要的reflush方法了,finishBeanFactoryInitialization(beanFactory);