所有文章
https://www.cnblogs.com/lay2017/p/11775787.html
正文
上一篇文章中,我們看到了DispatcherServlet和DispatcherServletRegistrationBean這兩個Bean的自動配置。DispatcherServlet我們很熟悉,DispatcherServletRegistrationBean負責將DispatcherServlet注冊到ServletContext當中。
DispatcherServletRegistrationBean的類圖
既然該類的職責是負責注冊DispatcherServlet,那么我們得知道什么時候觸發注冊操作。為此,我們先看看DispatcherServletRegistrationBean這個類的類圖
注冊DispatcherServlet流程
ServletContextInitializer
我們看到,最上面是一個ServletContextInitializer接口。我們可以知道,實現該接口意味着是用來初始化ServletContext的。我們看看該接口
public interface ServletContextInitializer { void onStartup(ServletContext servletContext) throws ServletException; }
RegistrationBean
看看RegistrationBean是怎么實現onStartup方法的
@Override public final void onStartup(ServletContext servletContext) throws ServletException { String description = getDescription(); if (!isEnabled()) { logger.info(StringUtils.capitalize(description) + " was not registered (disabled)"); return; } register(description, servletContext); }
調用了內部register方法,跟進它
protected abstract void register(String description, ServletContext servletContext);
這是一個抽象方法
DynamicRegistrationBean
再看DynamicRegistrationBean是怎么實現register方法的
@Override protected final void register(String description, ServletContext servletContext) { D registration = addRegistration(description, servletContext); if (registration == null) { logger.info(StringUtils.capitalize(description) + " was not registered (possibly already registered?)"); return; } configure(registration); }
跟進addRegistration方法
protected abstract D addRegistration(String description, ServletContext servletContext);
一樣是一個抽象方法
ServletRegistrationBean
再看ServletRegistrationBean是怎么實現addRegistration方法的
@Override protected ServletRegistration.Dynamic addRegistration(String description, ServletContext servletContext) { String name = getServletName(); return servletContext.addServlet(name, this.servlet); }
我們看到,這里直接將DispatcherServlet給add到了servletContext當中。
總結
總的來說,其實就是觸發了初始化ServletContext時候的回調接口onStartup方法,而后直接將DispatcherServlet作為一個Servlet給add到ServletContext當中。