spring-boot - Какой фрагмент кода на самом деле регистрирует диспетчерский сервлет для springMVC?
Я пытаюсь выяснить в spring-boot
, какая реализация WebApplicationInitializer
реально зарегистрировать диспетчерский сервлет.
Я не нашел никакого кода от SpringBootServletInitializer
или его родительские типы сделали это.
Вместо, AbstractDispatcherServletInitializer
делает работу, но это абстрактно, я не могу найти какую-либо конкретную реализацию с помощью Eclipse.
Итак, какой фрагмент кода из какого класса фактически вызывается для регистрации сервлета диспетчера для SpringMVC?
Это следующий вопрос: как spring-boot может обслуживать определенные URL?
3 ответа
Ниже приведено описание шагов инициализации Spring Boot, которые в конечном итоге регистрируются DispatcherServlet
,
Пример кода
@EnableAutoConfiguration
public class TestSpring {
public static void main(String[] args) throws Exception {
SpringApplication.run(TestSpring.class, args);
}
}
Шаги инициализации Spring Boot
Вот шаги:
SpringApplication.run()
создаетEmbeddedWebApplicationContext
контекст приложения;- Называет его
refresh()
Способ; - Процесс обновления читает аннотации начального класса
TestSpring
, Ищет импортные аннотации.EnableAutoConfiguration
это один из них. Для аннотации импорта процесс обновления получает соответствующий класс из аннотацииvalue
и вызывает егоselectImports()
Способ; - В случае
@EnableAutoConfiguration
соответствующий классEnableAutoConfigurationImportSelector
чьяselectImports()
загружает тонны других селекторов импорта изMETA-INF/spring.factories
; - Этот процесс продолжается рекурсивно. Кроме того, все определения компонентов, которые находятся внутри этих селекторов импорта, читаются. Т.е. он включает бины, определенные методом с
@Bean
аннотации, то есть bean-компоненты, которые требуют, чтобы контекст Spring автоматически вызывал соответствующий метод для их создания; -
resfresh()
продолжается и достигаетonRefresh()
,createEmbeddedServletContainer()
метод вызывается изнутри; - Среди операций чтения bean-компонентов на предыдущем шаге, реализация bean-компонентов
ServletContextInitializer
разыскиваются и создаются. Одним из них является боб, определяемыйDispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration#dispatcherServletRegistration()
методServletRegistrationBean
тип, который расширяетServletContextInitializer
, Как вы можете догадаться по названию класса, такие инициализаторы добавляют данный сервлет (в данном случае DispatcherServlet) к данномуServletContext
когда ихonStartup()
метод вызывается; - Создан встроенный сервер tomcat (еще не запущен полностью). Все найдено
ServletContextInitializer
s на предыдущем шаге передаются в эту инициализацию tomcat - это гдеonStartup()
методы техServletContextInitializer
называются иDispatcherServlet
создается и регистрируется как сервлет; - Конец чего-либо
onRefresh()
контекста приложения; -
finishRefresh()
называется там, где наконец начинается tomcatTomcatEmbeddedServletContainer.start()
; - Конец чего-либо
refresh()
контекста приложения и других заключительных этапов инициализации; - Приложение работает.
Когда вы ищете что-то, что Spring Boot делает во время автоконфигурации, вы должны посмотреть в *AutoConfiguration
классы. В этом случае, DispatcherServletAutoConfiguration
,
Если вы хотите развернуть приложение Spring Boot как традиционную WAR, то в спецификации Servlet 3.0 подробно описано, как поставщики услуг могут настроить его так, чтобы контейнер сервлета, совместимый с 3.0, автоматически загружал любые веб-ресурсы (Servlet, Filter, ServletContextInitializer's) в сервлет. контейнер. "Волшебство" достигается в зависимости от сети. Если вы отключите его, вы найдете файл "spring-web/META-INF/services/javax.servlet.ServletContainerInitializer". Откройте файл, и вы увидите одну строку "org.springframework.web.SpringServletContainerInitializer". Этот класс делегирует всем классам, которые реализуют WebApplicationInitializer, более конкретно их метод onStartup(ServletContext servletContext). В Spring Boot мне известен один такой конкретный класс, а именно SpringBootServletInitializer.