Springboot 原理篇(一)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    相信Springboot使用的越来越广泛了,约定大于配置,对于开发者使用确实是方便了,但是Springboot底层的原理清楚吗?下 
    面从源码一步一步来揭秘Springboot

    从Springboot入口Main函数分析
    public static void main(String[] args) {
        SpringApplication.run(XlbstudyApplication.class, args);
    }
    ···debug···
        public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
        return new SpringApplication(sources).run(args);
    }
    我们可以看到 new SpringApplication(sources).run(args) 
    重点:第一步 new SpringApplication
        private void initialize(Object[] sources) {
        if (sources != null && sources.length > 0) {
            //保存配置类
            this.sources.addAll(Arrays.asList(sources));
        }
        //判断是否是Web环境
        this.webEnvironment = deduceWebEnvironment();
        //重点  主要内容:从 META-INF/spring.factories 加载Initializers 
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
        //重点  主要内容:从 META-INF/spring.factories 加载Listeners
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        //选择 有main函数入口的配置类
        this.mainApplicationClass = deduceMainApplicationClass();
    }

    我们随便打开一个spring.factories文件看看 
    # Initializers
    org.springframework.context.ApplicationContextInitializer=\
    org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
    org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

    # Application Listeners
    org.springframework.context.ApplicationListener=\
    org.springframework.boot.autoconfigure.BackgroundPreinitializer


    重点: 第二步 run  
    run方法的代码如下
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch(); //这个就不解释了
        stopWatch.start();
        //定义一个ioc容器
        ConfigurableApplicationContext context = null;
        //定义一个失败分析器,用于异常分析的 
        FailureAnalyzers analyzers = null;
        //点进去可以发现是配置awt的 对我们正常的开发web应用没什么卵用
        configureHeadlessProperty();
        //重点 获取listener ,我们从第一步可以看到加载了listener 
        SpringApplicationRunListeners listeners = getRunListeners(args);
        //重点 回调 listenr的start方法
        listeners.starting();
        try {
            //包装web容器参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            //重点 准备环境变量 分析里面代码:listeners.environmentPrepared(environment);
            //回掉 listeners的 environmentPrepared 方法
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            //打印Banner 没卵用
            Banner printedBanner = printBanner(environment);
            //初始化 ioc容器
            context = createApplicationContext();
            //初始化
            analyzers = new FailureAnalyzers(context);
            /*重点 准备上下文容器: 
             *   回调初始化器
             *   initializer.initialize(context);
             *   回调 listener
             *   listeners.contextPrepared(context);
             */
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);
            /* 
             * 重中之重  spring ioc容器初始化,加载Spring bean 这个我们单独抽出来在讲重点会讲 
             * BeanPostProcessor后置处理器,其实xxAware ,@Autoword... 原理就是BeanPostProcessor
             * 后面我们在讲
             */
            refreshContext(context);
            /*
             * ioc容器初始化完成后 ,回调ApplicationRunner CommandLineRunner的run方法
             *  callRunner((ApplicationRunner ) runner, args);
             *  callRunner((CommandLineRunner) runner, args);
             */
            afterRefresh(context, applicationArguments);
            /*
             * 回调listener 的 finished方法
             */
            listeners.finished(context, null);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            return context;
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, analyzers, ex);
            throw new IllegalStateException(ex);
        }
    }

    总结:从上面的代码我们可以看到 Springboot为我们提供了4个组件 供我们扩展使用
    ApplicationContextInitializer
    ApplicationListener
    ApplicationRunner
    CommandLineRunner
    至于什么情况下会回调上面的组件 上诉源码写的很清楚了。但是核心的原理关键还是在refreshContext
    下面章节重点会讲解refreshContext,通过refreshContext源码可以知道Spring 扩展的原理,springboot 各种注解如 
    何实现,以及Springboot-start如何实现的

转载于:https://my.oschina.net/xliangbo/blog/2253903

你可能感兴趣的:(java,python)