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);
        }
    
    }
  • 相关阅读:
    json-c初探(一)
    Java程序员跳槽的首选面试题最新合集(2021下半年),初中高级程序员!
    R语言版本的bedtools--bedtoolsr
    使用R语言(cpm包)进行序列变点(change point)检测
    三款PHP大马,已解密、去后门
    php 取出数据表数据放入数组并排序
    VimTutor每讲小结
    记录一下c++学习过程
    vmware fusion关闭自动挂起(suspend)的方法
    mac中安装mysqlclient出错error: command 'clang' failed with exit status 1的解决办法
  • 原文地址:https://www.cnblogs.com/duanxz/p/11239018.html
Copyright © 2011-2022 走看看