前两节已经介绍了BeanFactoryPostProcessor的调用过程和BeanPostProcessor的初始化过程,我们继续分析refresh()方法。
9.初始化事件广播器
spring中的事件机制,也是典型的观察者模式的实现,如果大家对观察者模式不熟悉的话,可以先去了解一下,将有助于接下来的理解。现在来看事件广播器的初始化过程。
/**
* 初始化事件广播器
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 默认使用内置的事件广播器,如果有的话.
// 我们可以在配置文件中配置Spring事件广播器或者自定义事件广播器
// 例如: <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"></bean>
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
// 否则,新建一个事件广播器,SimpleApplicationEventMulticaster是spring的默认事件广播器
else {
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() + "]");
}
}
}
从代码中可以看到,Spring默认使用内置的事件广播器,例如我们可以在配置文件中定义一个事件广播器,注意beanName,
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
<!--事件广播器-->
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"></bean>
如果从BeanFactory中获取到了名为applicationEventMulticaster的事件广播器的话,那么就以此作为默认的事件广播器,如果未能获取的话,就要新建一个SimpleApplicationEventMulticaster类型的事件广播器,SimpleApplicationEventMulticaster也是Spring的默认事件广播器。
SimpleApplicationEventMulticaster–>AbstractApplicationEventMulticaster–>ApplicationEventMulticaster。
再加下来是onRefresh()方法,该方法是个空的模板方法,如果子类有需要的话,可以自己实现该方法,这也是spring的可扩展性的一个良好提现。
10.注册事件监听器
有了事件广播器之后,我们就要将事件监听器加入到事件广播器之后,以便事件广播器调用。
protected void registerListeners() {
// Register statically specified listeners first.
// 首先,注册指定的静态事件监听器,在spring boot中有应用
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!
// 其次,注册普通的事件监听器
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);
}
}
}
静态事件监听器和早期事件没搞明白,中间的普通事件监听器,我们可以通过实现ApplicationListener接口并重写onApplicationEvent来实现,通过xml配置文件来注册即可。
package com.lyc.cn.day06.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
/**
* @author: LiYanChao
* @create: 2018-09-26 10:53
*/
public class MyApplicationListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println("事件触发...");
}
}
<!--自定义事件监听器-->
<bean id="myApplicationListener" class="com.lyc.cn.day06.event.MyApplicationListener"></bean>
11.初始化其他的单例Bean(非延迟加载的)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 判断有无ConversionService(bean属性类型转换服务接口),并初始化
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// 如果beanFactory中不包含EmbeddedValueResolver,则向其中添加一个EmbeddedValueResolver
// EmbeddedValueResolver-->解析bean中的占位符和表达式
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 初始化LoadTimeWeaverAware类型的bean
// LoadTimeWeaverAware-->加载Spring Bean时织入第三方模块,如AspectJ
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
// 释放临时类加载器
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
// 冻结缓存的BeanDefinition元数据
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化其他的非延迟加载的单例bean
beanFactory.preInstantiateSingletons();
}
该过程比较简单,在初始化其他的非延迟加载的单例bean之前,预先加载了几个特殊的bean。
ConversionService–>判断有无自定义属性转换服务接口,并将其初始化,我们在分析bean的属性填充过程中,曾经用到过该服务接口。在TypeConverterDelegate类的convertIfNecessary方法中。
EmbeddedValueResolver–>内嵌的属性值解析器,主要用来解析bean中的占位符和表达式。
LoadTimeWeaverAware–>如果有LoadTimeWeaverAware类型的bean则初始化,用来加载Spring Bean时织入第三方模块,如AspectJ,我们在后面详细讲解。
最后初始化其他的普通的非延迟加载的bean,具体的代码如果大家看过之前的bean加载过程的话,应该很简单了,这里不再赘述。
12.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
// 清空资源缓存
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 初始化生命周期处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 调用生命周期处理器的onRefresh方法
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 推送容器刷新事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// MBean...没弄明白
LiveBeansView.registerApplicationContext(this);
}
- 初始化生命周期处理器
protected void initLifecycleProcessor() {
// 尝试从容器中获取lifecycleProcessor生命周期处理器
// 我们可以实现Lifecycle接口,并在配置文件中进行如下配置
// <bean id="myLifecycleBean" class="com.lyc.cn.day06.MyLifecycleBean"></bean>
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
// 如果没有的话,则创建一个DefaultLifecycleProcessor作为默认的生命周期处理器
else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
- 调用生命周期处理器的onRefresh方法
/**
* 启动LifecycleBean的start方法.
* autoStartupOnly:true-->则不会在这里启动
* :false-->启动
*/
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new HashMap<>();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
LifecycleGroup group = phases.get(phase);
if (group == null) {
group = new 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);
for (Integer key : keys) {
phases.get(key).start();
}
}
}
- 推送容器刷新事件
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
}
}
// Multicast right now if possible - or lazily once the multicaster is initialized
// 如果earlyApplicationEvents不为空
// 则说明早期事件不为空,则说明容器尚未初始化广播器,无法进行事件广播,我们将其存放到earlyApplicationEvents中
// 待容器初始化事件广播器之后,再进行事件广播
// 可以参考 registerListeners()方法
// 至于哪些事件是早期事件,我也没弄明白...
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
}
else {
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
// 通知父容器发布事件
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
// 如过有任务处理池的话,则默认使用任务处理池来进行异步处理
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
// 否则同步处理
else {
invokeListener(listener, event);
}
}
}
代码会继续调用doInvokeListener方法
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
try {
// 调动onApplicationEvent方法
listener.onApplicationEvent(event);
}
catch (ClassCastException ex) {
String msg = ex.getMessage();
if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) {
// Possibly a lambda-defined listener which we could not resolve the generic event type for
// -> let's suppress the exception and just log a debug message.
Log logger = LogFactory.getLog(getClass());
if (logger.isDebugEnabled()) {
logger.debug("Non-matching event type for listener: " + listener, ex);
}
}
else {
throw ex;
}
}
}
代码执行到listener.onApplicationEvent(event);
就会调用事件监听器的onApplicationEvent的方法,触发事件了。
ApplicationContext容器的refresh()方法讲到这里就结束了~