Spring源码(十二)reflush方法下的消息资源按和监视器初始化

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在正常的观察者模式中加入了一个事件驱动。以前都是被观察者调用方法,由方法触发对应的操作。这里把具体操作转换为一个事件。
在这里插入图片描述
执行过程:

  1. 事件源发布不同的事件。
  2. 当发布事件之后会调用多播器的方法来进行广播操作,由多播器去触发具体的监听器
  3. 监听器接收到具体的事件后,可以验证匹配是否能出来当前事件,如果不行,则不做任何操作。

实际代码处理:

  1. 提前准备好N个事件
  2. 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
  3. 准备好一系列监听器
  4. 向多播器注册已有的监听器
  5. 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作
	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。

总结

在这里插入图片描述
执行过程:

  1. 事件源发布不同的事件。
  2. 当发布事件之后会调用多播器的方法来进行广播操作,由多播器去触发具体的监听器
  3. 监听器接收到具体的事件后,可以验证匹配是否能出来当前事件,如果不行,则不做任何操作。

实际代码处理:

  1. 提前准备好N个事件
  2. 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
  3. 准备好一系列监听器
  4. 向多播器注册已有的监听器
  5. 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作

下面就到了最重要的reflush方法了,finishBeanFactoryInitialization(beanFactory);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值