本文由javacoder.cn整理,谢绝转载
@EnableAutoConfiguration本身的定义
@Import(AutoConfigurationPackages.Registrar.class) public @interface AutoConfigurationPackage{} @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {}
@Import的两个类的作用如下
AutoConfigurationPackages.Registrar 的作用是添加对@AutoConfigurationPackage注解作用的类所在包名的扫描,并将该包名下扫描到的需要注册的bean注册
EnableAutoConfigurationImportSelector对SpringFactoriesLoader 从"META-INF/spring.factories"中"key=org.springframework.boot.autoconfigure.EnableAutoConfiguration"加载的那一堆使用@Configuration注解的配置类的解析注册
spring-boot-autoconfigure-xxx.jar下的"META-INF/spring.factories"文件中定义了spring的工厂扩展机制。@EnableAutoConfiguration注解处理"key=org.springframework.boot.autoconfigure.EnableAutoConfiguration"对应的值(以逗号分隔,@Configuration注解的配置类),其中的org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration用于初始化嵌入式ServletContainer。
具体的实现参考如下方法
org.springframework.boot.autoconfigure.EnableAutoConfigurationImportSelector.selectImports()
org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass()解析入口配置类,也就是我们通过SpringApplication.run(Application.class, args);方法传入的使用@Configuration注解的类
org.springframework.context.annotation.ConfigurationClassPostProcessor对@EnableAutoConfiguration注解的处理
servlet 3.0 specification指定了编程式初始化servlet container的接口
javax.servlet.ServletContainerInitializer.onStartup(Set<Class<?>> c, ServletContext ctx) ;
而spring 将初始化ServletContainer的工作代理给WebApplicationInitializer接口,具体参考SpringServletContainerInitializer类的实现及注释
一个基于代码配置sevletContainer的示例如下,摘录自WebApplicationInitializer 的javadoc
public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { // Create the 'root' Spring application context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class); // Manage the lifecycle of the root application context container.addListener(new ContextLoaderListener(rootContext)); // Create the dispatcher servlet's Spring application context AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); dispatcherContext.register(DispatcherConfig.class); // Register and map the dispatcher servlet ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }
但是spring boot使用的是org.springframework.boot.context.embedded.ServletContextInitializer接口而不是WebApplicationInitializer,目的是为了不被ServletContainer自动初始化,具体的实现类为FilterRegistrationBean, ServletRegistrationBean,分别完成Filter和Servlet的注册
RequestMappingHandlerMapping.afterPropertiesSet()
完整的序列图如下
Posted in:MySQL practise