This default implementation is empty.
* @param bw the BeanWrapper to initialize
* @throws BeansException if thrown by BeanWrapper methods
* @see org.springframework.beans.BeanWrapper#registerCustomEditor
*/
protected void initBeanWrapper(BeanWrapper bw) throws BeansException {
}
```
- 然而实际上,子类暂时木有任何实现。
- `<2.4>` 处,以 Spring 的方式来将 `pvs` 注入到该 BeanWrapper 对象中,技设置到当前 Servlet 对象中。可能比较费解,我们还是举个例子。假设如下:
```
// web.xml
This implementation is empty.
* @param context the current WebApplicationContext
* @see #refresh()
*/
protected void onRefresh(ApplicationContext context) {
// For subclasses: do nothing by default.
}
```
- 这是一个空方法,具体的实现,在子类 DispatcherServlet 中。代码如下:
```
// DispatcherServlet.java
/**
* This implementation calls {@link #initStrategies}.
*/
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
// 初始化 MultipartResolver
initMultipartResolver(context);
// 初始化 LocaleResolver
initLocaleResolver(context);
// 初始化 ThemeResolver
initThemeResolver(context);
// 初始化 HandlerMappings
initHandlerMappings(context);
// 初始化 HandlerAdapters
initHandlerAdapters(context);
// 初始化 HandlerExceptionResolvers
initHandlerExceptionResolvers(context);
// 初始化 RequestToViewNameTranslator
initRequestToViewNameTranslator(context);
// 初始化 ViewResolvers
initViewResolvers(context);
// 初始化 FlashMapManager
initFlashMapManager(context);
}
```
- 这里,我们先不深究,在 DispatcherServlet 的初始化的文章中,详细解析。
------
`#onRefresh()` 方法,有两种方式被触发:
- 方式一,在
「4.3 initWebApplicationContext」
中,有两种情形,会触发。
- 情形一:情况一 + `wac` 已激活。
- 情形二:情况二。
- 这两种情形,此时 `refreshEventReceived` 为 `false` ,所以会顺着 `#initWebApplicationContext()` 方法的 `<3>` 的逻辑,调用 `#onRefresh()` 方法。😈 貌似说的有点绕,大家自己顺顺。
- 方式二,在
「4.3 initWebApplicationContext」
中,也有两种情况,会触发。不过相比方式一来说,过程会“曲折”一点。
- 情形一:情况一 + `wac` 未激活。
- 情形二:情况三。
- 这两种情形,都会调用 `#configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac)` 方法,在 `wac` 执行刷新完成后,会回调在该方法中,注册的 SourceFilteringListener 监听器。详细解析,见 [「5. SourceFilteringListener」](https://svip.iocoder.cn/Spring-MVC/context-init-Servlet-WebApplicationContext/#) 。
# 5. SourceFilteringListener
`org.springframework.context.event.SourceFilteringListener` ,实现 GenericApplicationListener、SmartApplicationListener 监听器,实现将原始对象触发的事件,转发给指定监听器。代码如下:
```
// SourceFilteringListener.java
public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener {
/**
* 原始类
*/
private final Object source;
/**
* 代理的监听器
*/
@Nullable
private GenericApplicationListener delegate;
/**
* Create a SourceFilteringListener for the given event source.
* @param source the event source that this listener filters for,
* only processing events from this source
* @param delegate the delegate listener to invoke with event
* from the specified source
*/
public SourceFilteringListener(Object source, ApplicationListener> delegate) {
this.source = source;
this.delegate = (delegate instanceof GenericApplicationListener ?
(GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate));
}
/**
* Create a SourceFilteringListener for the given event source,
* expecting subclasses to override the {@link #onApplicationEventInternal}
* method (instead of specifying a delegate listener).
* @param source the event source that this listener filters for,
* only processing events from this source
*/
protected SourceFilteringListener(Object source) {
this.source = source;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event.getSource() == this.source) { // 判断来源
onApplicationEventInternal(event);
}
}
@Override
public boolean supportsEventType(ResolvableType eventType) {
return (this.delegate == null || this.delegate.supportsEventType(eventType));
}
@Override
public boolean supportsEventType(Class extends ApplicationEvent> eventType) {
return supportsEventType(ResolvableType.forType(eventType));
}
@Override
public boolean supportsSourceType(@Nullable Class> sourceType) {
return (sourceType != null && sourceType.isInstance(this.source));
}
@Override
public int getOrder() {
return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE);
}
/**
* Actually process the event, after having filtered according to the
* desired event source already.
* The default implementation invokes the specified delegate, if any.
* @param event the event to process (matching the specified source)
*/
protected void onApplicationEventInternal(ApplicationEvent event) {
if (this.delegate == null) {
throw new IllegalStateException(
"Must specify a delegate object or override the onApplicationEventInternal method");
}
this.delegate.onApplicationEvent(event);
}
}
```
- 这个类的核心代码,就是 `#onApplicationEvent(ApplicationEvent event)` 方法中,判断事件的来源,就是原始类 `source` 。如果是,则调用 `#onApplicationEventInternal(ApplicationEvent event)` 方法,将事件转发给 `delegate` 监听器。
------
我们在回看下 `#configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac)` 方法,创建 SourceFilteringListener 对象时,传入的两个参数:
- `source` 属性,就是 `wac` 对象。
- `delegate` 属性,就是 ContextRefreshListener 对象。
下面,让我们来看看 ContextRefreshListener 具体的代码实现,代码如下:
```
// FrameworkServlet.java
private class ContextRefreshListener implements ApplicationListener