美文网首页Spring Coud
Spring Boot启动过程

Spring Boot启动过程

作者: 李小二的倔强 | 来源:发表于2019-05-27 18:00 被阅读0次

    Spring Boot启动过程

    好色风流 不是冤家不聚头 只为淫人妇 难保妻儿否 嬉戏眼前眸 孽满身后 报应从头 因此上 眉色邪淫一笔勾

    1. SpringApplication(ResourceLoader resourceLoader, Class<?>… primarySources) 是springboot的主启动方法
        public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
            this.resourceLoader = resourceLoader;
            Assert.notNull(primarySources, "PrimarySources must not be null");
            this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    // 1、判断web类型,此处是通过ClassUtils.isPresent()来读取类是否存在,决定环境类型
            this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //2 给定类型,然后从spring.factories文件加载初始化器
            setInitializers((Collection) getSpringFactoriesInstances(
                    ApplicationContextInitializer.class));
    // 3、给定类型,然后从spring.factories文件加载初始化器
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    // 使用StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(),
    // 获取堆栈信息,获取名称为main方法的全类名,赋值
            this.mainApplicationClass = deduceMainApplicationClass();
        }
    

    1、WebApplicationType.deduceFromClasspath() 方法进去之后将会看见判断环境的方法

        static WebApplicationType deduceFromClasspath() {
            if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
                    && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
                    && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
                return WebApplicationType.REACTIVE;
            }
            for (String className : SERVLET_INDICATOR_CLASSES) {
                if (!ClassUtils.isPresent(className, null)) {
                    return WebApplicationType.NONE;
                }
            }
            return WebApplicationType.SERVLET;
        }
    

    ClassUtils.isPresent(className, null) 进入后将看到具体的forName方法

        public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
                throws ClassNotFoundException, LinkageError {
    
            Assert.notNull(name, "Name must not be null");
    
            Class<?> clazz = resolvePrimitiveClassName(name);
            if (clazz == null) {
                clazz = commonClassCache.get(name);
            }
            if (clazz != null) {
                return clazz;
            }
    
            // "java.lang.String[]" style arrays
            if (name.endsWith(ARRAY_SUFFIX)) {
                String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
                Class<?> elementClass = forName(elementClassName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            }
    
            // "[Ljava.lang.String;" style arrays
            if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
                String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
                Class<?> elementClass = forName(elementName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            }
    
            // "[[I" or "[[Ljava.lang.String;" style arrays
            if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
                String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
                Class<?> elementClass = forName(elementName, classLoader);
                return Array.newInstance(elementClass, 0).getClass();
            }
    
            ClassLoader clToUse = classLoader;
            if (clToUse == null) {
                clToUse = getDefaultClassLoader();
            }
            try {
                return Class.forName(name, false, clToUse);
            }
            catch (ClassNotFoundException ex) {
                int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
                if (lastDotIndex != -1) {
                    String innerClassName =
                            name.substring(0, lastDotIndex) + INNER_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
                    try {
                        return Class.forName(innerClassName, false, clToUse);
                    }
                    catch (ClassNotFoundException ex2) {
                        // Swallow - let original exception get through
                    }
                }
                throw ex;
            }
        }
    
    

    2、进入getSpringFactoriesInstances( ApplicationContextInitializer.class) 方法后看到如下代码:

        private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, Object... args) {
            ClassLoader classLoader = getClassLoader();
            // Use names and ensure unique to protect against duplicates
            Set<String> names = new LinkedHashSet<>(
                    SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                    classLoader, args, names);
            AnnotationAwareOrderComparator.sort(instances);
            return instances;
        }
    

    createSpringFactoriesInstances(type, parameterTypes,
    classLoader, args, names) 进入方法后得到如下方法:

    private <T> List<T> createSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
                Set<String> names) {
            List<T> instances = new ArrayList<>(names.size());
            for (String name : names) {
                try {
                    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                    Assert.isAssignable(type, instanceClass);
                    Constructor<?> constructor = instanceClass
                            .getDeclaredConstructor(parameterTypes);
                    T instance = (T) BeanUtils.instantiateClass(constructor, args);
                    instances.add(instance);
                }
                catch (Throwable ex) {
                    throw new IllegalArgumentException(
                            "Cannot instantiate " + type + " : " + name, ex);
                }
            }
            return instances;
        }
    

    3、同上2的源码

    4、deduceMainApplicationClass() 进入方法得到如下方法:

        private Class<?> deduceMainApplicationClass() {
            try {
                StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
                for (StackTraceElement stackTraceElement : stackTrace) {
                    if ("main".equals(stackTraceElement.getMethodName())) {
                        return Class.forName(stackTraceElement.getClassName());
                    }
                }
            }
            catch (ClassNotFoundException ex) {
                // Swallow and continue
            }
            return null;
        }
    
    2.run(new Class<?>[] { primarySource }, args);
    public ConfigurableApplicationContext run(String... args) {
        // 1、创建并启动计时监控类
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 2、初始化应用上下文和异常报告集合
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        // 3、设置系统属性 `java.awt.headless` 的值,默认值为:true
        configureHeadlessProperty();
        // 4、创建所有 Spring 运行监听器并发布应用启动事件
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            // 5、初始化默认应用参数类
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);    
            // 6、根据运行监听器和应用参数来准备 Spring 环境
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            configureIgnoreBeanInfo(environment);
            // 7、创建 Banner 打印类
            Banner printedBanner = printBanner(environment);
            // 8、创建应用上下文
            context = createApplicationContext();
            // 9、准备异常报告器
            exceptionReporters = getSpringFactoriesInstances(
                    SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);     
            // 10、准备应用上下文
            prepareContext(context, environment, listeners, applicationArguments,
                    printedBanner);     
            // 11、刷新应用上下文
            refreshContext(context);
            // 12、应用上下文刷新后置处理
            afterRefresh(context, applicationArguments);
            // 13、停止计时监控类
            stopWatch.stop();
            // 14、输出日志记录执行主类名、时间信息
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            // 15、发布应用上下文启动完成事件
            listeners.started(context);
            // 16、执行所有 Runner 运行器
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }
        try {
            // 17、发布应用上下文就绪事件
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        // 18、返回应用上下文
        return context;
    }
     
    

    3、源码如下:

    设置系统属性 java.awt.headless 的值,默认值为:true
    对于一个 Java 服务器来说经常要处理一些图形元素,例如地图的创建或者图形和图表等。这些API基本上总是需要运行一个X-server以便能使用AWT(Abstract Window Toolkit,抽象窗口工具集)。然而运行一个不必要的 X-server 并不是一种好的管理方式。有时你甚至不能运行 X-server,因此最好的方案是运行 headless 服务器,来进行简单的图像处理。

    private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
    
    private boolean headless = true;
    
    private void configureHeadlessProperty() {
            System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty(
            SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
    }
    

    4、创建所有 Spring 运行监听器并发布应用启动事件,SpringApplicationRunListeners类。

    创建所有 Spring 运行监听器并发布应用启动事件
    void starting();
    void environmentPrepared(ConfigurableEnvironment environment);
    void contextPrepared(ConfigurableApplicationContext context);
    void contextLoaded(ConfigurableApplicationContext context);
    void started(ConfigurableApplicationContext context);
    void running(ConfigurableApplicationContext context);
    void failed(ConfigurableApplicationContext context, Throwable exception);

        public void starting() {
            for (SpringApplicationRunListener listener : this.listeners) {
                listener.starting();
            }
        }
    
            this.initialMulticaster.multicastEvent(new ApplicationContextInitializedEvent(
                    this.application, this.args, context));
    

    多路广播事件处理 :
    multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType)
    -| invokeListener(listener, event)
    -| doInvokeListener(listener, event)
    -| listener.onApplicationEvent(event)
    注 : onApplicationEvent(event),其实看到此方法就可以见到真正处理的代码了

        private SpringApplicationRunListeners getRunListeners(String[] args) {
            Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
            return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
                    SpringApplicationRunListener.class, types, this, args));
        }
    
        private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
            try {
                listener.onApplicationEvent(event);
            } catch (ClassCastException var6) {
                String msg = var6.getMessage();
                if(msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
                    throw var6;
                }
    
                Log logger = LogFactory.getLog(this.getClass());
                if(logger.isDebugEnabled()) {
                    logger.debug("Non-matching event type for listener: " + listener, var6);
                }
            }
    
        }
    
        private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, Object... args) {
            ClassLoader classLoader = getClassLoader();
            // Use names and ensure unique to protect against duplicates
            Set<String> names = new LinkedHashSet<>(
                    SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                    classLoader, args, names);
            AnnotationAwareOrderComparator.sort(instances);
            return instances;
        }
    
        private <T> List<T> createSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
                Set<String> names) {
            List<T> instances = new ArrayList<>(names.size());
            for (String name : names) {
                try {
                    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                    Assert.isAssignable(type, instanceClass);
                    Constructor<?> constructor = instanceClass
                            .getDeclaredConstructor(parameterTypes);
                    T instance = (T) BeanUtils.instantiateClass(constructor, args);
                    instances.add(instance);
                }
                catch (Throwable ex) {
                    throw new IllegalArgumentException(
                            "Cannot instantiate " + type + " : " + name, ex);
                }
            }
            return instances;
        }
    
        SpringApplicationRunListeners(Log log,
                Collection<? extends SpringApplicationRunListener> listeners) {
            this.log = log;
            this.listeners = new ArrayList<>(listeners);
        }
    

    6、根据运行监听器和应用参数来准备 Spring 环境

        private ConfigurableEnvironment prepareEnvironment(
                SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments) {
            // 创建和配置环境
            ConfigurableEnvironment environment = getOrCreateEnvironment();
                    //根据环境类和参数初始化环境
            configureEnvironment(environment, applicationArguments.getSourceArgs());
                   //初始化监听器  与`4.1`节处理逻辑相似
            listeners.environmentPrepared(environment);
            bindToSpringApplication(environment);
            if (!this.isCustomEnvironment) {
                environment = new EnvironmentConverter(getClassLoader())
                        .convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
            }
            ConfigurationPropertySources.attach(environment);
            return environment;
        }
    
        protected void configureEnvironment(ConfigurableEnvironment environment,
                String[] args) {
            if (this.addConversionService) {
                ConversionService conversionService = ApplicationConversionService
                        .getSharedInstance();
                environment.setConversionService(
                        (ConfigurableConversionService) conversionService);
            }
            configurePropertySources(environment, args);
            configureProfiles(environment, args);
        }
    
        private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {
            if (System.getProperty(
                    CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
                Boolean ignore = environment.getProperty("spring.beaninfo.ignore",
                        Boolean.class, Boolean.TRUE);
                System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME,
                        ignore.toString());
            }
        }
    
    

    7、创建 Banner 打印类

        private Banner printBanner(ConfigurableEnvironment environment) {
            if (this.bannerMode == Banner.Mode.OFF) {
                return null;
            }
            ResourceLoader resourceLoader = (this.resourceLoader != null)
                    ? this.resourceLoader : new DefaultResourceLoader(getClassLoader());
            SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(
                    resourceLoader, this.banner);
            if (this.bannerMode == Mode.LOG) {
                return bannerPrinter.print(environment, this.mainApplicationClass, logger);
            }
            return bannerPrinter.print(environment, this.mainApplicationClass, System.out);
        }
    

    8、创建应用上下文

        protected ConfigurableApplicationContext createApplicationContext() {
            Class<?> contextClass = this.applicationContextClass;
            if (contextClass == null) {
                try {
                    switch (this.webApplicationType) {
                    case SERVLET:
                        contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                        break;
                    case REACTIVE:
                        contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                        break;
                    default:
                        contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
                    }
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Unable create a default ApplicationContext, "
                                    + "please specify an ApplicationContextClass",
                            ex);
                }
            }
            return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
        }
    

    9、准备异常报告器

    初始化应用上下文和异常报告集合
    ConfigurableApplicationContext context = null;
    新建异常报告集合 ,在 9、准备异常报告器 中准备完成
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();

        private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, Object... args) {
            ClassLoader classLoader = getClassLoader();
            // Use names and ensure unique to protect against duplicates
            Set<String> names = new LinkedHashSet<>(
                    SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
                    classLoader, args, names);
            AnnotationAwareOrderComparator.sort(instances);
            return instances;
        }
    
        private <T> List<T> createSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
                Set<String> names) {
            List<T> instances = new ArrayList<>(names.size());
            for (String name : names) {
                try {
                    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                    Assert.isAssignable(type, instanceClass);
                    Constructor<?> constructor = instanceClass
                            .getDeclaredConstructor(parameterTypes);
                    T instance = (T) BeanUtils.instantiateClass(constructor, args);
                    instances.add(instance);
                }
                catch (Throwable ex) {
                    throw new IllegalArgumentException(
                            "Cannot instantiate " + type + " : " + name, ex);
                }
            }
            return instances;
        }
    

    10、准备应用上下文

        private void prepareContext(ConfigurableApplicationContext context,
                ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
                ApplicationArguments applicationArguments, Banner printedBanner) {
            // // 设置环境
            context.setEnvironment(environment);
            //  回调方法,Spring容器创建之后做一些额外的事
            postProcessApplicationContext(context);
           //SpringApplication的的初始化器开始工作
            applyInitializers(context);
           // 遍历调用SpringApplicationRunListener的contextPrepared方法。
           // 目前只是将这个事件广播器注册到Spring容器中
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }
            //添加特定于引导的单例bean
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
            beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
            if (printedBanner != null) {
                beanFactory.registerSingleton("springBootBanner", printedBanner);
            }
            if (beanFactory instanceof DefaultListableBeanFactory) {
                ((DefaultListableBeanFactory) beanFactory)
                        .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
            }
            // 加载资源
            Set<Object> sources = getAllSources();
            Assert.notEmpty(sources, "Sources must not be empty");
                   // 读取主类数据loader.load();
            load(context, sources.toArray(new Object[0]));
                  //遍历调用SpringApplicationRunListener的contextLoaded方法。
            listeners.contextLoaded(context);
        }
    
    
        protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
            if (this.beanNameGenerator != null) {
                context.getBeanFactory().registerSingleton(
                        AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
                        this.beanNameGenerator);
            }
            if (this.resourceLoader != null) {
                if (context instanceof GenericApplicationContext) {
                    ((GenericApplicationContext) context)
                            .setResourceLoader(this.resourceLoader);
                }
                if (context instanceof DefaultResourceLoader) {
                    ((DefaultResourceLoader) context)
                            .setClassLoader(this.resourceLoader.getClassLoader());
                }
            }
            if (this.addConversionService) {
                context.getBeanFactory().setConversionService(
                        ApplicationConversionService.getSharedInstance());
            }
        }
    

    在刷新上下文之前,将任何 ApplicationContextInitializer 应用于上下文。

        protected void applyInitializers(ConfigurableApplicationContext context) {
            for (ApplicationContextInitializer initializer : getInitializers()) {
                Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(
                        initializer.getClass(), ApplicationContextInitializer.class);
                Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
                initializer.initialize(context);
            }
        }
    

    为了记录启动信息,子类可以重写以添加附加日志记录。

        protected void logStartupInfo(boolean isRoot) {
            if (isRoot) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarting(getApplicationLog());
            }
        }
    

    调用此函数以记录活动概要信息。

    protected void logStartupProfileInfo(ConfigurableApplicationContext context) {
            Log log = getApplicationLog();
            if (log.isInfoEnabled()) {
                String[] activeProfiles = context.getEnvironment().getActiveProfiles();
                if (ObjectUtils.isEmpty(activeProfiles)) {
                    String[] defaultProfiles = context.getEnvironment().getDefaultProfiles();
                    log.info("No active profile set, falling back to default profiles: "
                            + StringUtils.arrayToCommaDelimitedString(defaultProfiles));
                }
                else {
                    log.info("The following profiles are active: "
                            + StringUtils.arrayToCommaDelimitedString(activeProfiles));
                }
            }
        }
    

    将bean加载到应用程序上下文中。

        protected void load(ApplicationContext context, Object[] sources) {
            if (logger.isDebugEnabled()) {
                logger.debug(
                        "Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
            }
            BeanDefinitionLoader loader = createBeanDefinitionLoader(
                    getBeanDefinitionRegistry(context), sources);
            if (this.beanNameGenerator != null) {
                loader.setBeanNameGenerator(this.beanNameGenerator);
            }
            if (this.resourceLoader != null) {
                loader.setResourceLoader(this.resourceLoader);
            }
            if (this.environment != null) {
                loader.setEnvironment(this.environment);
            }
            loader.load();
        }
    
        /**
         * 将源代码加载到阅读器中。
         * @return the number of loaded beans
         */
        public int load() {
            int count = 0;
            for (Object source : this.sources) {
                count += load(source);
            }
            return count;
        }
    

    11、刷新应用上下文

        private void refreshContext(ConfigurableApplicationContext context) {
            refresh(context);
            if (this.registerShutdownHook) {
                try {
                    context.registerShutdownHook();
                }
                catch (AccessControlException ex) {
                    // 在某些环境中是不允许的。
                }
            }
        }
    

    返回静态指定的Applicationisteners列表。

    public void refresh() throws BeansException, IllegalStateException {
            Object var1 = this.startupShutdownMonitor;
            synchronized(this.startupShutdownMonitor) {
                // 准备好刷新上下文
                this.prepareRefresh();
                // 告诉子类刷新内部bean工厂。
                ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
                // 准备bean工厂,以便在此上下文中使用。
                this.prepareBeanFactory(beanFactory);
                try {
                    // 允许在上下文子类中对bean工厂进行后处理。
                    this.postProcessBeanFactory(beanFactory);
                    // 调用上下文中注册为bean的工厂处理器。
                    this.invokeBeanFactoryPostProcessors(beanFactory);
                    // 注册拦截bean创建的bean处理器。
                    this.registerBeanPostProcessors(beanFactory);
                    // 初始化此上下文的消息源。
                    this.initMessageSource();
                    // 初始化此上下文的事件多播程序
                    this.initApplicationEventMulticaster();
                    // 在特定上下文子类中初始化其他特殊bean。
                    this.onRefresh();
                    // 检查侦听器bean并注册它们。
                    this.registerListeners();
                    // 实例化所有剩余的(非惰性初始化)单例。
                    this.finishBeanFactoryInitialization(beanFactory);
                    // 最后一步:发布相应的事件。
                    this.finishRefresh();
                } catch (BeansException var9) {
                    if(this.logger.isWarnEnabled()) {
                        this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                    }
                    // 销毁已经创建的单例,以避免挂起资源。
                    this.destroyBeans();
                    // 重置“活跃”的旗帜。
                    this.cancelRefresh(var9);
                    // 将异常传播给调用者。
                    throw var9;
                } finally {
                    // 重置Spring核心中的公共内省缓存,因为我们可能再也不需要单例bean的元数据了……
                    this.resetCommonCaches();
                }
    
            }
        }
    

    设置Spring容器的启动时间,撤销关闭状态,开启活跃状态。
    初始化属性源信息(Property)
    验证环境信息里一些必须存在的属性

        protected void prepareRefresh() {
            this.startupDate = System.currentTimeMillis();
            this.closed.set(false);
            this.active.set(true);
            if(this.logger.isDebugEnabled()) {
                if(this.logger.isTraceEnabled()) {
                    this.logger.trace("Refreshing " + this);
                } else {
                    this.logger.debug("Refreshing " + this.getDisplayName());
                }
            }
    
            this.initPropertySources();
            this.getEnvironment().validateRequiredProperties();
            if(this.earlyApplicationListeners == null) {
                this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);
            } else {
                this.applicationListeners.clear();
                this.applicationListeners.addAll(this.earlyApplicationListeners);
            }
    
            this.earlyApplicationEvents = new LinkedHashSet();
        }
    
    

    1.设置classloader(用于加载bean),设置表达式解析器(解析bean定义中的一些表达式),添加属性编辑注册器(注册属性编辑器)
    2.添加ApplicationContextAwareProcessor这个BeanPostProcessor。取消ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、EnvironmentAware这5个接口的自动注入。因为ApplicationContextAwareProcessor把这5个接口的实现工作做了
    3.设置特殊的类型对应的bean。BeanFactory对应刚刚获取的BeanFactory;ResourceLoader、ApplicationEventPublisher、ApplicationContext这3个接口对应的bean都设置为当前的Spring容器
    4.注入一些其它信息的bean,比如environment、systemProperties等

        protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            //设置classloader(用于加载bean)
            beanFactory.setBeanClassLoader(this.getClassLoader());
            设置表达式解析器(解析bean定义中的一些表达式)
            beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
            //添加属性编辑注册器(注册属性编辑器)
            beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
            //添加ApplicationContextAwareProcessor这个BeanPostProcessor。
            //取消ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、
            //EnvironmentAware这5个接口的自动注入。
            //因为ApplicationContextAwareProcessor把这5个接口的实现工作做了
            beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
            beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
            beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
            beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
            beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
            beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
            beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
            beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
            beanFactory.registerResolvableDependency(ResourceLoader.class, this);
            beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
            beanFactory.registerResolvableDependency(ApplicationContext.class, this);
            beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
            //注入一些其它信息的bean,比如environment、systemProperties等
            if(beanFactory.containsBean("loadTimeWeaver")) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
    
            if(!beanFactory.containsLocalBean("environment")) {
                beanFactory.registerSingleton("environment", this.getEnvironment());
            }
    
            if(!beanFactory.containsLocalBean("systemProperties")) {
                beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
            }
    
            if(!beanFactory.containsLocalBean("systemEnvironment")) {
                beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
            }
    
        }
    

    invokeBeanFactoryPostProcessors(beanFactory)—>
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory,getBeanFactoryPostProcessors())—>
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)

        public static void invokeBeanFactoryPostProcessors(
                ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
            // 如果有的话,首先调用beandefinition reqistrypostprocessor。
            Set<String> processedBeans = new HashSet<>();
    
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
                List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    }
                    else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    
                // 不要在这里初始化factorvbean:我们需要不初始化所有常规bean,让bean工厂后处理程序应用于它们!
                // 将实现erioritvordered的beandefinition registrypostprocessor分开。点的,还有其他的。
                List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
                // 首先,调用实现priorityorated的beandefinition registrypostprocessor。
                String[] postProcessorNames =
                        beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // 接下来,调用实现Ordered的beandefinitionrecistrypostprocessor。
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                        processedBeans.add(ppName);
                    }
                }
                sortPostProcessors(currentRegistryProcessors, beanFactory);
                registryProcessors.addAll(currentRegistryProcessors);
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                currentRegistryProcessors.clear();
    
                // 最后,调用所有其他beandefinitionregistrypostprocessor,直到没有其他bean出现
                boolean reiterate = true;
                while (reiterate) {
                    reiterate = false;
                    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                    for (String ppName : postProcessorNames) {
                        if (!processedBeans.contains(ppName)) {
                            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                            processedBeans.add(ppName);
                            reiterate = true;
                        }
                    }
                    sortPostProcessors(currentRegistryProcessors, beanFactory);
                    registryProcessors.addAll(currentRegistryProcessors);
                    //链路调用此方法
                    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
                    currentRegistryProcessors.clear();
                }
    
                // 现在,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
            }
    
            else {
                // 使用上下文实例调用reqistered工厂处理器。
                invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
            }
    
            // 不要在这里初始化factorybean:我们需要不初始化所有reqular bean,让pean factory后处理程序应用于它们!
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // 将实现优先化ed的beanfactorypostprocessor与其他处理器分开。
            List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
            List<String> orderedPostProcessorNames = new ArrayList<>();
            List<String> nonOrderedPostProcessorNames = new ArrayList<>();
            for (String ppName : postProcessorNames) {
                if (processedBeans.contains(ppName)) {
                    // 跳过-已经在上面的第一阶段处理
                }
                else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                }
                else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                }
                else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    
            // 首先,调用实现priorityordering的beanfactorypostprocessor。
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // 接下来,调用实现ordered的beanfactorypostprocessor。
            List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : orderedPostProcessorNames) {
                orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            sortPostProcessors(orderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // 最后,调用所有其他beanfactorypostprocessor。
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
            // 清除缓存的合并bean定义,因为后处理程序可能修改了原始元数据,例如替换值中的占位符……
            beanFactory.clearMetadataCache();
        }
    
        /**
         * 调用给定的BeanDefinitionReqistryPostProcessor bean。
         */
        private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }
    

    postProcessor.postProcessBeanDefinitionRegistry(registry)—>

        // ConfigurationClassPostProcessor类中的方法
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
            int registryId = System.identityHashCode(registry);
            if(this.registriesPostProcessed.contains(Integer.valueOf(registryId))) {
                throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
            } else if(this.factoriesPostProcessed.contains(Integer.valueOf(registryId))) {
                throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
            } else {
                this.registriesPostProcessed.add(Integer.valueOf(registryId));
                this.processConfigBeanDefinitions(registry);
            }
        }
    

    processConfigBeanDefinitions(registry)[创建config bean]—>
    **读取主类包中的@Component注解 : **
    ComponentScanAnnotationParser读取@ComponentScan注解,通过parse()加载packages属性.
    Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass)
    Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass)
    declaringClass是传入的主类,默认会读取该类的包位置

        public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
            List<BeanDefinitionHolder> configCandidates = new ArrayList();
            String[] candidateNames = registry.getBeanDefinitionNames();
            String[] var4 = candidateNames;
            int var5 = candidateNames.length;
    
            for(int var6 = 0; var6 < var5; ++var6) {
                String beanName = var4[var6];
                BeanDefinition beanDef = registry.getBeanDefinition(beanName);
                if(!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
                    if(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
                        configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
                    }
                } else if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
                }
            }
    
            if(!configCandidates.isEmpty()) {
                configCandidates.sort((bd1, bd2) -> {
                    int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
                    int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
                    return Integer.compare(i1, i2);
                });
                SingletonBeanRegistry sbr = null;
                if(registry instanceof SingletonBeanRegistry) {
                    sbr = (SingletonBeanRegistry)registry;
                    if(!this.localBeanNameGeneratorSet) {
                        BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");
                        if(generator != null) {
                            this.componentScanBeanNameGenerator = generator;
                            this.importBeanNameGenerator = generator;
                        }
                    }
                }
    
                if(this.environment == null) {
                    this.environment = new StandardEnvironment();
                }
    
                ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
                Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);
                HashSet alreadyParsed = new HashSet(configCandidates.size());
    
                do {
                    parser.parse(candidates);
                    parser.validate();
                    Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses());
                    configClasses.removeAll(alreadyParsed);
                    if(this.reader == null) {
                        this.reader = new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry());
                    }
    
                    this.reader.loadBeanDefinitions(configClasses);
                    alreadyParsed.addAll(configClasses);
                    candidates.clear();
                    if(registry.getBeanDefinitionCount() > candidateNames.length) {
                        String[] newCandidateNames = registry.getBeanDefinitionNames();
                        Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));
                        Set<String> alreadyParsedClasses = new HashSet();
                        Iterator var12 = alreadyParsed.iterator();
    
                        while(var12.hasNext()) {
                            ConfigurationClass configurationClass = (ConfigurationClass)var12.next();
                            alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
                        }
    
                        String[] var23 = newCandidateNames;
                        int var24 = newCandidateNames.length;
    
                        for(int var14 = 0; var14 < var24; ++var14) {
                            String candidateName = var23[var14];
                            if(!oldCandidateNames.contains(candidateName)) {
                                BeanDefinition bd = registry.getBeanDefinition(candidateName);
                                if(ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                                    candidates.add(new BeanDefinitionHolder(bd, candidateName));
                                }
                            }
                        }
    
                        candidateNames = newCandidateNames;
                    }
                } while(!candidates.isEmpty());
    
                if(sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
                    sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
                }
    
                if(this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
                    ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();
                }
    
            }
        }
    
    

    ComponentScanAnnotationParser读取@ComponentScan注解,通过parse()加载packages属性.

        public void parse(Set<BeanDefinitionHolder> configCandidates) {
            Iterator var2 = configCandidates.iterator();
    
            while(var2.hasNext()) {
                BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
                BeanDefinition bd = holder.getBeanDefinition();
    
                try {
                    if(bd instanceof AnnotatedBeanDefinition) {
                        this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
                    } else if(bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
                        this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
                    } else {
                        this.parse(bd.getBeanClassName(), holder.getBeanName());
                    }
                } catch (BeanDefinitionStoreException var6) {
                    throw var6;
                } catch (Throwable var7) {
                    throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
                }
            }
    
            this.deferredImportSelectorHandler.process();
        }
    
    
        protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
            processConfigurationClass(new ConfigurationClass(metadata, beanName));
        }
    
        protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
            if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
                return;
            }
    
            ConfigurationClass existingClass = this.configurationClasses.get(configClass);
            if (existingClass != null) {
                if (configClass.isImported()) {
                    if (existingClass.isImported()) {
                        existingClass.mergeImportedBy(configClass);
                    }
                    // 否则忽略新导入的配置类;现有的非导入类覆盖它。
                    return;
                }
                else {
                    // 找到显式bean定义,可能替换导入。
                                    // 让我们把旧的拿掉,换上新的。
                    this.configurationClasses.remove(configClass);
                    this.knownSuperclasses.values().removeIf(configClass::equals);
                }
            }
    
            // 递归地处理配置类及其超类层次结构。
            SourceClass sourceClass = asSourceClass(configClass);
            do {
                sourceClass = doProcessConfigurationClass(configClass, sourceClass);
            }
            while (sourceClass != null);
    
            this.configurationClasses.put(configClass, configClass);
        }
    
    

    12、应用上下文刷新后置处理

    在刷新上下文之后调用。

        protected void afterRefresh(ConfigurableApplicationContext context,
                ApplicationArguments args) {
        }
    

    13、停止计时监控类

    停止当前任务。如果在不调用至少一对的情况下调用计时方法,则结果是未定义的

        public void stop() throws IllegalStateException {
            if (this.currentTaskName == null) {
                throw new IllegalStateException("Can't stop StopWatch: it's not running");
            }
            long lastTime = System.currentTimeMillis() - this.startTimeMillis;
            this.totalTimeMillis += lastTime;
            this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
            if (this.keepTaskList) {
                this.taskList.add(this.lastTaskInfo);
            }
            ++this.taskCount;
            this.currentTaskName = null;
        }
    

    14、输出日志记录执行主类名、时间信息

        public void logStarted(Log log, StopWatch stopWatch) {
            if (log.isInfoEnabled()) {
                log.info(getStartedMessage(stopWatch));
            }
        }
    
        private StringBuilder getStartedMessage(StopWatch stopWatch) {
            StringBuilder message = new StringBuilder();
            message.append("Started ");
            message.append(getApplicationName());
            message.append(" in ");
            message.append(stopWatch.getTotalTimeSeconds());
            try {
                double uptime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000.0;
                message.append(" seconds (JVM running for " + uptime + ")");
            }
            catch (Throwable ex) {
                // No JVM time available
            }
            return message;
        }
    

    15、发布应用上下文启动完成事件

        default void publishEvent(ApplicationEvent event) {
            this.publishEvent((Object)event);
        }
    

    16、执行所有 Runner 运行器

        private void callRunners(ApplicationContext context, ApplicationArguments args) {
            List<Object> runners = new ArrayList<>();
            runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
            runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
            AnnotationAwareOrderComparator.sort(runners);
            for (Object runner : new LinkedHashSet<>(runners)) {
                if (runner instanceof ApplicationRunner) {
                    callRunner((ApplicationRunner) runner, args);
                }
                if (runner instanceof CommandLineRunner) {
                    callRunner((CommandLineRunner) runner, args);
                }
            }
        }
    
        private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
            try {
                (runner).run(args);
            }
            catch (Exception ex) {
                throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
            }
        }
    

    相关文章

      网友评论

        本文标题:Spring Boot启动过程

        本文链接:https://www.haomeiwen.com/subject/jwihtctx.html