本文由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