6.3 自动配置类DispatcherServletAutoConfiguration
6.3.1 DispatcherServletAutoConfiguration类的讲解
DispatcherServlet是通过Spring Boot自动配置的机制注册到IOC容器中的。自动配置类名称为DispatcherServletAutoConfiguration,该自动配置类定义在spring-boot- autoconfigure-2.3.7.RELEASE.jar包的org.springframework.boot.autoconfigure. web包中,如图6-14所示。
图6-14 DispatcherServletAutoConfiguration自动配置类
DispatcherServletAutoConfiguration类的源码及注释如下所示:
DispatcherServletAutoConfiguration类中有两个静态内部类,分别为DispatcherServletConfiguration类和DispatcherServletRegistrationConfiguration类,这三个类的定义都有一些条件注解,表示类的生效条件。
DispatcherServletAutoConfiguration类的注解释义如下所示。
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE):类的加载顺序,数值越小越优先加载。
@Configuration(proxyBeanMethods = false):指定该类为配置类。
@ConditionalOnWebApplication(type = Type.SERVLET):当前应用是一个Servlet Web应用,这个配置类才生效。
@ConditionalOnClass(DispatcherServlet.class):判断当前classpath是否存在DispatcherServlet类,存在则生效。
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class):自动配置的生效时间在ServletWebServerFactoryAutoConfiguration类之后。
通过源码可知,DispatcherServletAutoConfiguration自动配置类的自动配置触发条件:当前项目类型必须为SERVLET且当前classpath存在DispatcherServlet类(因为当前项目引入了spring-boot-starter-web场景启动器,该启动器包含了相关依赖,因此两个条件都需要满足,自动配置类才会生效)。而@AutoConfigureAfter注解又定义了自动配置类生效时间在ServletWebServerFactory自动配置之后。
DispatcherServletConfiguration类的注解释义如下所示。
@Configuration(proxyBeanMethods = false):指定该类为配置类。
@Conditional(DefaultDispatcherServletCondition.class):在DefaultDispatcherServlet Condition条件类被满足的情况下该配置类才会生效。
@ConditionalOnClass(ServletRegistration.class):判断当前classpath是否存在指定类,若存在则实例化当前类。
@EnableConfigurationProperties(WebMvcProperties.class):实例化WebMvcProperties配置属性类。
通过源码可知,DispatcherServletConfiguration自动配置类的自动配置触发条件:在DefaultDispatcherServletCondition条件类被满足且当前classpath存在ServletRegistration类时才会注册DispatcherServle至IOC容器中。DefaultDispatcherServletCondition条件类的主要逻辑是判断在BeanFactory中是否已经存在DispatcherServlet实例,不存在才会触发。在触发后程序将会读取application.properties配置文件或者在application.yml配置文件中读取spring.http和spring.mvc前缀的配置项并完成配置。
DispatcherServletRegistrationConfiguration类的注解释义如下所示。
@Configuration(proxyBeanMethods = false):指定该类为配置类。
@Conditional(DispatcherServletRegistrationCondition.class):在DispatcherServlet RegistrationCondition条件类被满足的情况下该配置类才会生效。
@ConditionalOnClass(ServletRegistration.class):判断当前classpath是否存在指定类,若存在则实例化当前类。
@EnableConfigurationProperties(WebMvcProperties.class):实例化WebMvcProperties配置属性类。
通过源码可知,DispatcherServletConfiguration自动配置类的自动配置触发条件:在DispatcherServletRegistrationCondition条件类被满足且当前classpath存在ServletRegistration类时才会注册DispatcherServletRegistrationBean至IOC容器中。DispatcherServletRegistrationCondition条件类的主要逻辑是判断在当前BeanFactory中是否已经存在DispatcherServlet实例和DispatcherServletRegistration实例,DispatcherServlet存在且DispatcherServletRegistration不存在才会触发。
6.3.2 DispatcherServletAutoConfiguration在IOC容器中的注册
通过前文的条件注解分析可知,当自动配置流程开始且条件被满足后,自动配置类DispatcherServletAutoConfiguration在进行自动配置时会注册一个名称为“dispatcherServlet”的Bean至IOC容器中。这就是文章中一直提到的Spring MVC的核心分发器DispatcherServlet。在Spring Boot项目中之所以可以不进行配置,是因为自动配置类会将其注册到IOC容器中。
在DispatcherServlet注册成功之后会继续注册一个名称为“dispatcherServlet Registration”的Bean至IOC容器中。这个DispatcherServletRegistrationBean有点特殊,它并不是一个普通意义上的Bean。在类定义中可以看到它实现了ServletContextInitializer接口。DispatcherServletRegistrationBean继承路径如图6-15所示。
图6-15 DispatcherServletRegistrationBean继承路径
ServletContextInitializer接口用于以编程的方式配置Servlet 3.0+的上下文,它在DispatcherServlet装载中起到了重要作用。后文也会提到这个知识点。该接口的详细内容可以参照Spring官方文档:ServletContextInitializer-doc.html。