【spring】源码-spring 容器启动过程之初始化(九)

 

 

目录

initMessageSource()

1.getBeanFactory()

1.1 DefaultListableBeanFactory

initApplicationEventMulticaster()

onRefresh()

 registerListeners()方法


initMessageSource()

为 应用上下文初始化信息资源;即初始化 MessageSource 对象;

	protected void initMessageSource() {
		// 获取bean 工厂,默认DefaultListableBeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//判断容器中是否已经存在id是messageSource的bean 对象
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			//存在就回去该对象
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			//  判断工厂类存在父类 并且 messageSource 属于HierarchicalMessageSource 类型
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				// 向上转型获取HierarchicalMessageSource
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				//判断父类内部messageSource 为空 就进行设置
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					// 把父类消息相关信息设置
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using MessageSource [" + this.messageSource + "]");
			}
		}
		// 容器中不存在messageSource 对象
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			// 实例化一个DelegatingMessageSource 对象 作为messageSource 的bean对象
			DelegatingMessageSource dms = new DelegatingMessageSource();
			// 把父类消息相关信息设置
			dms.setParentMessageSource(getInternalParentMessageSource());
			// 把DelegatingMessageSource 赋值给上下文messageSource
			this.messageSource = dms;
			// 然后把 messageSource 注册到工厂中
			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 + "]");
			}
		}
	}
东方鲤鱼

解析:因为DelegatingMessageSource类实现了HierarchicalMessageSource接口,而这个接口继承了MessageSource这个类,实现了这个接口的类,都是MessageSource的子类,因此DelegatingMessageSource也是一个MessageSource
 

                                         这里写图片描述

 

 

HierarchicalMessageSource接口
添加了两个方法,建立父子层级的MessageSource结构。该接口的setParentMessageSource (..)方法用于设置父MessageSource,而getParentMessageSource()方法用于返回父MessageSource。

ResourceBundleMessageSource和ReloadableResourceBundleMessageSource
它们基于Java的ResourceBundle基础类实现,可以通过资源名加载国际化资源。ReloadableResourceBundleMessageSource提供了定时刷新功能,允许在不重启系统的情况下,更新资源的信息。StaticMessageSource主要用于程序测试,它允许通过编程的方式提供国际化信息。而DelegatingMessageSource是为方便操作父MessageSource而提供的代理类。
 

1.getBeanFactory()

该方法定义在AbstractApplicationContext类,实现在AbstractRefreshableApplicationContext 抽象类中,该类继承了 AbstractApplicationContext 类;



    @Nullable
	private DefaultListableBeanFactory beanFactory;




	@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;
		}
	}

默认实例化一个 DefaultListableBeanFactory 工厂类对象返回;

1.1 DefaultListableBeanFactory

DefaultListableBeanFactory 类实现了 ConfigurableListableBeanFactory与BeanDefinitionRegistry;

ConfigurableListableBeanFactory 提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题);主要成员方法有

  1、2个忽略自动装配的的方法。

  2、1个注册一个可分解依赖的方法。

  3、1个判断指定的Bean是否有资格作为自动装配的候选者的方法。

  4、1个根据指定bean名,返回注册的Bean定义的方法。

  5、2个冻结所有的Bean配置相关的方法。

  6、1个使所有的非延迟加载的单例类都实例化的方法。

 

ApplicationContext实现了MessageSource的接口。ApplicationContext的实现类本身也是一个MessageSource对象。

ApplicationContext.initMessageSource()方法所执行的工作就是初始化容器中的国际化信息资源:它从BeanDefinitionRegistry中找出名称为“messageSource”且类型为MessageSource的Bean,将这个Bean定义的信息资源加载为容器级的国际化信息资源;
 

initApplicationEventMulticaster()

 

protected void initApplicationEventMulticaster() {
		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 + "]");
			}
		}
	}

解析 :ApplicationEventMulticaster 接口:实现该接口的对象可以管理多个 ApplicationListener 对象,并发布事件给 他们;一个 ApplicationEventPublisher,通常是 一个 Spring 的 ApplicationContext,可以使用 ApplicationEventMuticaster 作为 委托实际处发布事件;

       SimpleApplicationEventMulticaster 类:ApplicationEventMulticaster 简单的实现类;多路广播 所有的事件 给 所有已注册的 监听器(listener);

先判断有没有自定义的ApplicationEventMulticaster,没有的话就注册一个。SimpleApplicationEventMulticaster就是用来发布事件用的;

 

onRefresh()

在特殊的context子类中初始化其他的特殊bean.这里的相关子类是 AbstractRefreshableWebApplicationContext ,其重写方法如下:

@Override
	protected void onRefresh() {
		this.themeSource = UiApplicationContextUtils.initThemeSource(this);
	}

UiApplicationContextUtils: UI 上下文应用的功能类,对 名称为 themeSource 的 特殊的 bean 提供支持;

	public static ThemeSource initThemeSource(ApplicationContext context) {
		// 判断容器中是否存在hemeSource id 的对象
		if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
			// 存在就获取
			ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
			// Make ThemeSource aware of parent ThemeSource.
			if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
				HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
				if (hts.getParentThemeSource() == null) {
					// Only set parent context as parent ThemeSource if no parent ThemeSource
					// registered already.
					// 给父级设置
					hts.setParentThemeSource((ThemeSource) context.getParent());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using ThemeSource [" + themeSource + "]");
			}
			return themeSource;
		}
		else {
			// Use default ThemeSource to be able to accept getTheme calls, either
			// delegating to parent context's default or to local ResourceBundleThemeSource.
			HierarchicalThemeSource themeSource = null;
			if (context.getParent() instanceof ThemeSource) {
				//  实例化一个DelegatingThemeSource 对象
				themeSource = new DelegatingThemeSource();
				themeSource.setParentThemeSource((ThemeSource) context.getParent());
			}
			else {
				themeSource = new ResourceBundleThemeSource();
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
						"': using default [" + themeSource + "]");
			}
			return themeSource;
		}
	}
东方鲤鱼

解析:ThemeSource 接口:实现类 可以 解决 Theme;可以为 指定的 theme 提供 消息的参数化 和 国际化 ;
           HierarchicalThemeSource 接口:子接口,实现类可以 解决 消息 的 继承关系;

1)判断是否存在名字为“ThemeSource”的bean

2)如果存在判断父context是否实现了ThemeSource接口,这个context是否实现了HierarchicalThemeSource接口.如果全部符合,设置父ThemeSource。

3)如果不存在设置判断父context是否实现了ThemeSource接口,如果实现了则实例化DelegatingThemeSource并且设置父ThemeSource。如果没有实现实例化ResourceBundleThemeSource。

 registerListeners()方法

检查 listener bean 并注册;

protected void registerListeners() {
		// Register statically specified listeners first.
		//  getApplicationListeners就是获取applicationListeners
		//是通过applicationListeners(listener)添加,放入applicationListeners中
		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);
		}

		// Publish early application events now that we finally have a multicaster...
		//发布
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}东方鲤鱼

  解析:前期默认注册监听器;

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方鲤鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值