SpringBoot擴展點之三:SpringBootServletInitializer擴展

SpringBootServletInitializerjava

熟悉了SpringApplication的原理以後,咱們再來了解SpringBootServletInitializer的原理就比較容易了。web

public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(DemoWarApplication.class); } } 

SpringBootServletInitializer就是一個org.springframework.web.context.WebApplicationContext,容器啓動時會調用其onStartup(ServletContext servletContext)方法,接下來我麼就來看一下這個方法:spring

public void onStartup(ServletContext servletContext) throws ServletException { this.logger = LogFactory.getLog(this.getClass()); final WebApplicationContext rootAppContext = this.createRootApplicationContext(servletContext); if(rootAppContext != null) { servletContext.addListener(new ContextLoaderListener(rootAppContext) { public void contextInitialized(ServletContextEvent event) { } }); } else { this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context"); } } 

這裏的核心方法就是createRootApplicationContext(servletContext):app

protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) { //建立SpringApplicationBuilder,並用其生產出SpringApplication對象 SpringApplicationBuilder builder = this.createSpringApplicationBuilder(); builder.main(this.getClass()); ApplicationContext parent = this.getExistingRootWebApplicationContext(servletContext); if(parent != null) { this.logger.info("Root context already created (using as parent)."); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (Object)null); builder.initializers(new ApplicationContextInitializer[]{new ParentContextApplicationContextInitializer(parent)}); } //初始化並封裝SpringApplicationBuilder對象,爲SpringApplication對象增長ApplicationContextInitializer和ApplicationListener作準備 builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)}); builder.listeners(new ApplicationListener[]{new ServletContextApplicationListener(servletContext)}); //指定建立的ApplicationContext類型 builder.contextClass(AnnotationConfigEmbeddedWebApplicationContext.class); //傳遞入口類,並構建SpringApplication對象 //能夠經過configure()方法對SpringBootServletInitializer進行擴展 builder = this.configure(builder); SpringApplication application = builder.build(); if(application.getSources().isEmpty() && AnnotationUtils.findAnnotation(this.getClass(), Configuration.class) != null) { application.getSources().add(this.getClass()); } Assert.state(!application.getSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation"); if(this.registerErrorPageFilter) { application.getSources().add(ErrorPageFilter.class); } //最後調用SpringApplication的run方法 return this.run(application); } 

說明
SpringBootServletInitializer的執行過程,簡單來講就是經過SpringApplicationBuilder構建並封裝SpringApplication對象,並最終調用SpringApplication的run方法的過程。ide


擴展SpringBootServletInitializer

與擴展SpringApplication相似,ApplicationContextInitializerApplicationListener能夠基於SpringApplicationBuilder提供的public方法進行擴展ui

public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { application.initializers(MyApplicationContextInitializer1,MyApplicationContextInitializer2); application.listeners(MyApplicationListener1,MyApplicationListener2) return application.sources(DemoWarApplication.class); } }
相關文章
相關標籤/搜索