目录
1.1 DefaultListableBeanFactory
initApplicationEventMulticaster()
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);
}
}
}东方鲤鱼
解析:前期默认注册监听器;