SpringApplication.class 设置初始化
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
设置
classpath 下的ApplicationContextInitializer.class 全部实例化
classpath 下的ApplicationListener.class 全部实例化
方法 run
SpringApplicationRunListeners listeners = getRunListeners(args);
classpath下的SpringApplicationRunListener.class(包含所有的ApplicationListener.class) 全部实例化
内容初始化
debug 内容
1.1 方法public ConfigurableApplicationContext run(String... args) 为什么会走2次?
一次是
org.springframework.cloud.bootstrap.BootstrapApplicationListener 监听器执行所导致
一个是本身自己 AnnotationConfigServletWebServerApplicationContext
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
类图结构:
2.1 在ServletWebServerApplicationContext创建一个webServer
2.2则会查到bean 定义中查找 类型为ServletWebServerFactory.class 类
3.1
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration
自动配置类
TomcatServletWebServerFactory类图所示
TomcatServletWebServerFactory getWebServer() 方法中创建tomcat
3.2 在获取tomcat webserver, 则要对容器初始化(如,servlet, Filter, EventListener, ServletContextInitializer) 封装成RegistrationBean等。
this:: selfInitialize() 是回调函数,那么实际方法selfInitialize()那么时候什么时候才会被调用?
根据断点得知,执行完一下代码,才会执行实际的代码。
则会将ServletContextInitializer.class 类型的从容器加载。
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean
类图下,属于就子类
自动配置类中: DispatcherServletRegistrationBean 定义到容器中
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
二 跨域解决
Request -> FilterChain(filter) -> Servlet(HandlerInterceptor);
在filter 解决跨域问题(推荐使用).
@Configuration
public class CorsFilterConfig {
public CorsConfiguration corsConfiguration() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
//可配置化
corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList("*"));
corsConfiguration.setAllowedOrigins(Arrays.asList("*"));
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration());
CorsFilter corsFilter = new CorsFilter(urlBasedCorsConfigurationSource);
return corsFilter;
}
}
在DispatcherServlet中springmvc WebMvcConfigurer中解决跨域
/**
* @author dahai
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("*")
.maxAge(3600);
WebMvcConfigurer.super.addCorsMappings(registry);
}
}