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);
        }
    
    }
  • 相关阅读:
    long和Long的区别
    C语言的变量的内存分配
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
  • 原文地址:https://www.cnblogs.com/duanxz/p/11239018.html
Copyright © 2011-2022 走看看