zoukankan      html  css  js  c++  java
  • SpringBoot扩展点之三:SpringBootServletInitializer扩展

    SpringBootServletInitializer

    熟悉了SpringApplication的原理之后,我们再来了解SpringBootServletInitializer的原理就比较容易了。

    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)方法,接下来我么就来看一下这个方法:

    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):

    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方法的过程。


    扩展SpringBootServletInitializer

    与扩展SpringApplication类似,ApplicationContextInitializerApplicationListener可以基于SpringApplicationBuilder提供的public方法进行扩展

    public class ServletInitializer extends SpringBootServletInitializer {
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            application.initializers(MyApplicationContextInitializer1,MyApplicationContextInitializer2);
            application.listeners(MyApplicationListener1,MyApplicationListener2)
            return application.sources(DemoWarApplication.class);
        }
    
    }
  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/duanxz/p/11239018.html
Copyright © 2011-2022 走看看