目录
2.initApplicationEventMulticaster
4.finishBeanFactoryInitialization
到目前,容器的启动过程还剩下下面几个方法:
this.initMessageSource(); //初始化消息源,用于国际化
this.initApplicationEventMulticaster(); //初始化应用程序的事件广播器
this.onRefresh(); //空方法,作为扩展点
this.registerListeners(); //查找并注册Listener Bean
this.finishBeanFactoryInitialization(beanFactory); //初始化剩余的单例
this.finishRefresh(); //完成刷新,并通知相关监听器
1.initMessageSource
MessageSource的作用是进行国际化,initMessageSource方法源码如下:
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("messageSource")) {
this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(this.getInternalParentMessageSource());
}
}
} else {
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(this.getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton("messageSource", this.messageSource);
}
}
该方法首先在容器中查找是否有名为“messageSource”的Bean,如果有,则获取它,假如它是HierarchicalMessageSource类型,则为其设置ParentMessageSource;如果没有,则新建一个DelegatingMessageSource对象,并为其创建单例实例。无论哪种情况,都会将其赋给类成员变量messageSource。从这段代码中,可以看到,假如说我们自己实现了一个MessageSource,在XML配置时,其id属性必须是“messageSource”,否则将不会生效,这里隐含的另一个限制就是,容器内只能有一个MessageSource生效。
HierarchicalMessageSource和DelegatingMessageSource都是MessageSource的子类,前者的两个实现类ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,都是基于Java的ResourceBundle实现的,可以通过资源名加载国际化资源,ReloadableResourceBundleMessageSource可以在不重启程序的情况下更新国际化资源;DelegatingMessageSource主要用于父MessageSource。
需要提取出Message时,可以通过context.getMessage()方法,在ResourceBundleMessageSource中,该方法实际就是调用MessageSource的getMessageInternal方法,可以看到,MessageSource实质就是Locale和MessageFormat的封装:
protected String getMessageInternal(@Nullable String code, @Nullable Object[] args, @Nullable Locale locale) {
if (code == null) {
return null;
} else {
if (locale == null) {
locale = Locale.getDefault();
}
Object[] argsToUse = args;
if (!this.isAlwaysUseMessageFormat() && ObjectUtils.isEmpty(args)) {
String message = this.resolveCodeWithoutArguments(code, locale);
if (message != null) {
return message;
}
} else {
argsToUse = this.resolveArguments(args, locale);
MessageFormat messageFormat = this.resolveCode(code, locale);
if (messageFormat != null) {
synchronized(messageFormat) {
return messageFormat.format(argsToUse);
}
}
}
Properties commonMessages = this.getCommonMessages();
if (commonMessages != null) {
String commonMessage = commonMessages.getProperty(code);
if (commonMessage != null) {
return this.formatMessage(commonMessage, args, locale);
}
}
return this.getMessageFromParent(code, argsToUse, locale);
}
}
2.initApplicationEventMulticaster
该方法的内容和initMessageSource的非常相似,同样限制了我们在XML中配置自定义实现时的id:
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
} else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
}
}
可以看到,容器的默认实现是SimpleApplicationEventMulticaster,当我们通过容器的publishEvent方法发布一个事件时,就会调用自身或父容器的来广播事件:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
...
this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
} else {
this.parent.publishEvent(event);
}
}
}
而multicastEvent方法就是遍历ApplicationListener列表,逐个触发(假如Executor不为空,则使用Executor异步触发):
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Iterator var4 = this.getApplicationListeners(event, type).iterator();
while(var4.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var4.next();
Executor executor = this.getTaskExecutor();
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
配置Executor的方法是,使用Spring的task标签:
<beans ... xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="...
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">
<task:executor id="executor" pool-size="5"/>
<bean class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="executor"></property>
</bean>
</beans>
3.registerListeners
上一节说到,ApplicationEventMulticaster实现广播的方法就是,遍历在自己这里注册的监听器列表,逐个触发,所以registerListener方法就是向广播器注册监听器的过程。这里没有像之前的两个方法一样按照名字查找Bean,而是像PostProcessor一样按照类型查找,因此是不限数量,也不限id属性的:
protected void registerListeners() {
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;
for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
Iterator var9 = earlyEventsToProcess.iterator();
while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
这里有一个过程是,假如有些事件是提前事件,即在Bean解析之后、监听器注册之前就已经实例化并触发的事件(例如Bean注册完成后会触发广播,虽然源码里是空实现,但是可以通过扩展的方式真正触发),就会在此先进行处理。
4.finishBeanFactoryInitialization
到上一步结束时,容器的扩展已经基本结束了,此时要做的就是对某些Bean进行预先实例化,同时冻结BeanDefinition,即在下次refresh之前,已经完成配置的Bean都不能再被修改了。
首先,检查容器是否配置了ConversionService,同样限定了id:
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
接下来,如果没注册过后处理器,则注册一个StringValueResolver,主要作用是处理注解参数:
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
然后实例化实现了LoadTimeWeaverAware接口的Bean:
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
临时ClassLoader用来进行类型匹配,此处已经用不上了,可以置空:
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
freezeConfiguration用于设置标记位,表名设置冻结;
preInstantiateSingletons从名字来看,是提前实例化单例。首先会实例化所有没有设置init-lazy="true"的bean:
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
FACTORY_BEAN_PREFIX是"&"。代码整体逻辑还是很清晰的,首先是进行判断,假如说bean是抽象的,那么肯定不能实例化,如果scope不是singleton,也没必要创建单例(prototype类型的bean随用随创建),如果是懒加载的,也不需要这时候实例化。然后判断bean是否是FactoryBean,即Bean是否实现了FactoryBean接口,用户可以通过实现该接口定制实例化Bean的逻辑,即Bean自身是否是一个工厂。同时还需要传入的Bean是SmartFactoryBean,且其isEagerInit方法返回true(接口中default实现返回false)。
然后触发所有Bean单例的初始化后的回调方法。这里要求单例实例必须是SmartInitializingSingleton类型,该接口只有一个afterSingletonsInstantiated方法。
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
5.finishRefresh
finishRefresh方法一共做了三件事:清理资源缓存、初始化并刷新生命周期处理器、发布容器刷新完毕事件。清理资源缓存实际就是执行其内部存储Resource对象的Map的clear方法,发布事件也不陌生,所以主要看生命周期处理器的相关内容。
Lifecycle接口包含start/stop方法,Spring容器启动时会执行其实现类的start方法,关闭时执行其stop方法。
该步骤由两个方法组成,第一个是initLifecycleProcessor方法,和initMessageSource、initApplicationEventMulticaster类似,都是先查找指定id“lifecycleProcessor”的Bean,有则赋给成员变量,否则实例化默认类型DefaultLifecycleProcessor,并为其创建和注册单例:
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("lifecycleProcessor")) {
this.lifecycleProcessor = (LifecycleProcessor)beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton("lifecycleProcessor", this.lifecycleProcessor);
}
}
第二个是getLifecycleProcessor().onRefresh(),以DefaultLifecycleProcessor的实现为例,实际执行了startBeans方法:
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = this.getLifecycleBeans();
Map<Integer, DefaultLifecycleProcessor.LifecycleGroup> phases = new HashMap();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || bean instanceof SmartLifecycle && ((SmartLifecycle)bean).isAutoStartup()) {
int phase = this.getPhase(bean);
DefaultLifecycleProcessor.LifecycleGroup group = (DefaultLifecycleProcessor.LifecycleGroup)phases.get(phase);
if (group == null) {
group = new DefaultLifecycleProcessor.LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList(phases.keySet());
Collections.sort(keys);
Iterator var5 = keys.iterator();
while(var5.hasNext()) {
Integer key = (Integer)var5.next();
((DefaultLifecycleProcessor.LifecycleGroup)phases.get(key)).start();
}
}
}
首先获取了实现Lifecycle接口的Bean,然后检查它们是否是SmartLifecycle类型且允许自动启动,是则获取该Bean所处的生命周期阶段,封装为LifecycleGroup对象并添加到Map中。然后执行每个Group的所有成员的start方法。
相应的,当容器关闭时,由于其注册了虚拟机的关闭钩子,所以会执行doClose方法进行安全关机,在这之中,我们也看到了LifecycleProcessor的身影:
protected void doClose() {
...
if (this.lifecycleProcessor != null) {
try {
this.lifecycleProcessor.onClose();
} catch (Throwable var2) {
this.logger.warn("Exception thrown from LifecycleProcessor on context close", var2);
}
}
...
}
这里通过onClose方法,间接调用了stopBeans方法,其核心内容就是执行LifecycleGroup对象的stop方法。