zoukankan      html  css  js  c++  java
  • 源码阅读简记~springboot启动

    起点代码,通过main方法启动springboot程序

    @SpringBootApplication
    public class Main {
        public static void main(String[] args) {
            SpringApplication app = new SpringApplication(Main.class);
            app.run(args);
        }
    }

    Main方法中有两步:

    step1:为构造器初始化,构造器调用到initialize方法,结合META-INF/spring.factories,初始化各种资源

    private void initialize(Object[] sources) { // sources -> [class cloud.simple.hello.Main]
            if (sources != null && sources.length > 0) {
                this.sources.addAll(Arrays.asList(sources));
            }
            this.webEnvironment = deduceWebEnvironment();
            setInitializers((Collection) getSpringFactoriesInstances(
                    ApplicationContextInitializer.class));
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
            this.mainApplicationClass = deduceMainApplicationClass();
        }

    通过反省反射工厂方式,生成实例

    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
    Constructor<?> constructor = instanceClass.getConstructor(parameterTypes);
    T instance = (T) constructor.newInstance(args);

    step2:run。

    public ConfigurableApplicationContext run(String... args) {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            configureHeadlessProperty();
            SpringApplicationRunListeners listeners = getRunListeners(args); // 老套路同上,加载并初始化启动
            listeners.started();
            try {
                ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                        args);
                context = createAndRefreshContext(listeners, applicationArguments);
                afterRefresh(context, applicationArguments);
                listeners.finished(context, null);
                stopWatch.stop();
                if (this.logStartupInfo) {
                    new StartupInfoLogger(this.mainApplicationClass)
                            .logStarted(getApplicationLog(), stopWatch);
                }
                return context;
            }
            catch (Throwable ex) {
                handleRunFailure(context, listeners, ex);
                throw new IllegalStateException(ex);
            }
        }

    关键创建步骤,bean生命周期加载,容器创建及启动

    private ConfigurableApplicationContext createAndRefreshContext(
                SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments) {
            ConfigurableApplicationContext context;
            // Create and configure the environment
            ConfigurableEnvironment environment = getOrCreateEnvironment();
            configureEnvironment(environment, applicationArguments.getSourceArgs());
            listeners.environmentPrepared(environment);
            if (isWebEnvironment(environment) && !this.webEnvironment) {
                environment = convertToStandardEnvironment(environment);
            }
    
            if (this.bannerMode != Banner.Mode.OFF) {
                printBanner(environment);
            }
    
            // Create, load, refresh and run the ApplicationContext
            context = createApplicationContext();
            context.setEnvironment(environment);
            postProcessApplicationContext(context);
            applyInitializers(context);
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }
    
            // Add boot specific singleton beans
            context.getBeanFactory().registerSingleton("springApplicationArguments",
                    applicationArguments);
    
            // Load the sources
            Set<Object> sources = getSources();
            Assert.notEmpty(sources, "Sources must not be empty");
            load(context, sources.toArray(new Object[sources.size()]));
            listeners.contextLoaded(context);
    
            // Refresh the context
            refresh(context);
            if (this.registerShutdownHook) {
                try {
                    context.registerShutdownHook();
                }
                catch (AccessControlException ex) {
                    // Not allowed in some environments.
                }
            }
            return context;
        }

    refresh

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // Prepare the bean factory for use in this context.
                prepareBeanFactory(beanFactory);
    
                try {
                    // Allows post-processing of the bean factory in context subclasses.
                    postProcessBeanFactory(beanFactory);
    
                    // Invoke factory processors registered as beans in the context.
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // Register bean processors that intercept bean creation.
                    registerBeanPostProcessors(beanFactory);
    
                    // Initialize message source for this context.
                    initMessageSource();
    
                    // Initialize event multicaster for this context.
                    initApplicationEventMulticaster();
    
                    // Initialize other special beans in specific context subclasses.
                    onRefresh();
    
                    // Check for listener beans and register them.
                    registerListeners();
    
                    // Instantiate all remaining (non-lazy-init) singletons.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // Last step: publish corresponding event.
                    finishRefresh();
                }
    
                catch (BeansException ex) {
                    if (logger.isWarnEnabled()) {
                        logger.warn("Exception encountered during context initialization - " +
                                "cancelling refresh attempt: " + ex);
                    }
    
                    // Destroy already created singletons to avoid dangling resources.
                    destroyBeans();
    
                    // Reset 'active' flag.
                    cancelRefresh(ex);
    
                    // Propagate exception to caller.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }

    容器创建时机

        @Override
        protected void onRefresh() {
            super.onRefresh();
            try {
                createEmbeddedServletContainer();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Unable to start embedded container",
                        ex);
            }
        }

    刷新后创建容器

        @Override
        protected void onRefresh() {
            super.onRefresh();
            try {
                createEmbeddedServletContainer();
            }
            catch (Throwable ex) {
                throw new ApplicationContextException("Unable to start embedded container",
                        ex);
            }
        }

    容器启动 TomcatEmbeddedServletContainer implements EmbeddedServletContainer

        @Override
        public void start() throws EmbeddedServletContainerException {
            try {
                addPreviouslyRemovedConnectors();
                Connector connector = this.tomcat.getConnector();
                if (connector != null && this.autoStart) {
                    startConnector(connector);
                }
                // Ensure process isn't left running if it actually failed to start
                if (connectorsHaveFailedToStart()) {
                    stopSilently();
                    throw new IllegalStateException("Tomcat connector in failed state");
                }
                TomcatEmbeddedServletContainer.logger
                        .info("Tomcat started on port(s): " + getPortsDescription(true));
            }
            catch (Exception ex) {
                throw new EmbeddedServletContainerException(
                        "Unable to start embedded Tomcat servlet container", ex);
            }
        }
  • 相关阅读:
    JavaScript访问ab页面定时跳转代码
    http协议相关-待续
    curl发送get和post请求
    Java入门——动态网页jsp(jdk下载和配置环境变量)
    LeetCode:Best Time to Buy and Sell Stock
    LeetCode:Reverse Integer
    LeetCode:Same Tree
    LeetCode:Single Number II
    LeetCode:Single Number
    LeetCode:Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/it-worker365/p/14737765.html
Copyright © 2011-2022 走看看