SpringBoot源码分析

SpringBoot源码分析

1、Spring和springboot是关系是什么?

Springboot是spring就是最核心的产品之一(是spring的分支项目),当然就包含springmvc。springmvc 只是spring 处理web层请求的一个模块。

Springboot是构建在spring基础之上的一个产品,其主要目的就是简化spring框架中繁复的配置问题,用什么方式来解决的呢?

用注解和类完成的

无论使用spring还是springboot开发,其本质来说,springboot都是在做一件事情,就把项目中的bean初始化放入到spring的ioc容器中,springboot是构建在spring基础之上的一个解决方案(框架)。springboot提供了非常丰富的的初始化bean的解决方案:比如:@Configuration+Bean、SelectorImport机制 、@Enablexxx开关类等。

springboot不管如何使用都脱离不了springioc容器。

SpringBoot源码分析_第1张图片

2、SpringBoot什么时候把这些所谓机制加载到ioc容器?

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mapper")
public class StudyBootsAdminApplication {

    public static void main(String[] args) {
        SpringApplication.run(StudyBootsAdminApplication.class, args);
    }

}

在执行main函数启动时,就会调用类加载器去加载对应的bean,全部放入到到ioc容器中

2.1 什么是类加载器

SpringApplication.run(AdminApplication.class, args); 中的:AdminApplication.class 传递了一个类,目的是为了触发类加载器和通过反射找到主类上的注解@SpringBootApplication

2.2 可以传递别的类吗?

不可以,因为传递别的类,没办法去加载项目中bean和加载starter机制的类。

因为主类上有一个注解@SpringBootApplication ,这个注解是核心注解。它会去加载项目中对应的所有的bean,包含项目@Configuration+@Bean的初始化、@Import机制(starter)这些类等等。

为什么要触发类加载器?

  • 可以获取上下文的环境,获取系统的信息
  • 会加载pom.xml所有的依赖jar中编译好的类
  • 会加载jdk对应api

传递类的作用:为了触发类加载和通过反射找到主类上的核心注解@SpringBootApplication,然后再触发springboot中的机制,把项目中和pom.xml中的依赖(starter和其他的依赖jar)、以及jdk的api全部初始化到内存中。其中springboot中通过@Configuration+@Bean的初始化、@SelectorImport机制(starter)和扫包+注解、@ImportResource加载配置文件都会放入到ioc容器中。

3、Springboot是如何做到所谓的零配置(少量配置文件)呢?

3.1 传统ssm方式

  • xml – applicationContext.xml

    <bean id="xxx" class="xxxx">
    <bean id="xxx" class="xxxx">
    <bean id="xxx" class="xxxx">
    <bean id="xxx" class="xxxx">
    <bean id="xxx" class="xxxx">
    
  • 扫包 + 注解

    <component-scan basePackeges="com.kuangstudy.service">
    <component-scan basePackeges="com.kuangstudy.mapper">
    <component-scan basePackeges="com.kuangstudy.controller">
    

    注解:@Service、@Controller、@RestContoller、@Respostity、@Component等

3.2 SpringBoot改进

  • 扫包(注解) + 注解

    @ComponentScan + 注解:@Service、@Controller、@RestContoller、@Respostity、@Component等
    
  • @Configuration+@Bean 配置类 + @Bean初始化

  • @Import机制

    @Import(配置类&selector即可实现类,你也可以写普通bean)
    @Import(RedisConfiguration.class)
    @Import(UserService.class)
    @Import(AxxxxSelector.class)
    
  • @ImportResource

    @ImportResource("classpath:applicationContext.xml")
    
  • 抛弃传统的xml方式

  • 可以集合整合传统的xml方式 通过@ImportResource来整合即可。不建议混合使用。

4、springboot提供的注解@SpringBootApplication 能够解决什么?作用是什么?

@SpringBootApplication是一个复合注解:

  • @Configuration+@Bean
  • @SelectorImport机制
  • @ImportResource
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@Target(ElementType.TYPE) :jdk注解中代表当前注解只能使用类上面,注解使用范围
@Retention(RetentionPolicy.RUNTIME):代表该注解类的,可以通过反射获取到注解信息。、
@Documented jdk注解文档
@Inherited 允许注解继承


核心注解
@SpringBootConfiguration 等价于:@Configuration(@Component) + @Bean
@EnableAutoConfiguration 这个就是开关注解 + @SelectorImport机制来加载bean到ioc容器中
@ComponentScan+注解(@Service、@Controller、@RestController、@Component 、@Repository)

@EnableAutoConfiguration 就是开关注解 + @SelectorImport机制来加载bean到ioc容器中。同时它也是去加载项目中starter机制的注解。为什么要使用:@SelectorImport机制 + @Eablexxxxx这些机制呢?

5、@Configuration+@Bean加载到ioc容器的规则

前提:@Configuration+@Bean 必须配合:@ComponentScan 才能把对象的bean放入到ioc容器中。

为什么要配置@ComponentScan才能发挥效果?

通过@Configuration注解的源码如下可以得知:原理是一个@Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration 

@Configuraiton注解的类

被@Configuraiton注解的类叫配置类:一般是用来初始化bean到ioc容器中的一种机制。但是这个机制必须要配置扫包==@ComponentScan==才能发挥作用。

  • 配置类相当于:applicationContext.xml

  • 配置类中@Bean节点相当于:applicationContext.xml中节点。

package com.example.entity;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/9:22
 * @Description:
 */
public class User {

    private Integer id;
    private String nickname;
    private String password;
}
package com.example.service;

import com.example.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/9:23
 * @Description:
 */
@Slf4j
public class UserService {

    @Autowired
    private User user;

    public void saveUser() {
        log.info("你保存的用户是:{}", user);
    }
}
package com.example.config;

import com.example.entity.User;
import com.example.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/9:34
 * @Description:
 */
@Configuration
public class UserConfiguration {

    @Bean
    @Primary
    public User getUser(){
        User user = new User();
        user.setId(1);
        user.setNickname("刘大");
        user.setPassword("123456");
        return user;
    }

    @Bean
    public UserService getUserService(){
        return new UserService();
    }
}
package com.example;

import com.example.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class StudyBootsSourceApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    void contextLoads() {
        userService.saveUser();
    }

}

6、@ComponentScan+注解(@Service、@Controller、@RestController、@Component 、@Repository)

默认情况:@ComponentScan默认的扫包范围是当前启动类的包。

作用:把该包下com.example;的所有的子包和子孙包下面所有的符合条件的类(@Service、@Controller、@RestController、@Component 、@Repository)和 @Configuration类全部加载到ioc容器中。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
// 通过暴露确实可以把当前主类包之外的类加载到ioc容器中,但是它会覆盖默认的规则。不会再加载主包下面的bean
@ComponentScan(basePackages ={"com.redis","com.example"})
public class StudyBootsSourceApplication {

        public static void main(String[] args) {
        SpringApplication.run(KuangstudyBootsSourceApplication.class, args);
    }
}

9、为什么要使用@Import机制 + @Eablexxxxx这些机制呢?

9.1 剖析@EnableAutoConfiguration注解

@EnableAutoConfiguration源码如下:

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    Class<?>[] exclude() default {};
    String[] excludeName() default {};
}

核心代码:

@Import(AutoConfigurationImportSelector.class)

@Import机制里放入了class。 这个class可以是configuration类也可以是ImportSelector子类

9.2 @Import例子

springboot提供一种新的方式可以把bean放入的ioc容器中

9.2.1 定义bean
package com.example.importSelector;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/12:55
 * @Description:
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserCourseBean {

    private String nickname = "刘大";
    private String password = "123456";
}
package com.example.importSelector;

import lombok.extern.slf4j.Slf4j;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/13:01
 * @Description:
 */
@Slf4j
public class UserOrderService {

    public void makeOrder(Integer userId, String orderId) {
        log.info("用户:{},下单成功:订单id是:{}", userId, orderId);
    }
}
9.2.2 定义开关类

作用:是否让springboot去加载bean到ioc容器中,如果需要配置类上增加注解即可。

package com.example.importSelector;

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/12:58
 * @Description:
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(UserCourseImportSelector.class)
public @interface EnableUserCourse {
}
9.2.3 定义具体的import的实现类
package com.example.importSelector;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @Auther: 长颈鹿
 * @Date: 2021/08/03/13:04
 * @Description:
 */
public class UserCourseImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{
                "com.example.importSelector.UserCourseBean",
                "com.example.importSelector.UserOrderService"
        };
    }
}

ImportSelector是一个接口:

package org.springframework.context.annotation;

import java.util.function.Predicate;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;


public interface ImportSelector {
    
	String[] selectImports(AnnotationMetadata importingClassMetadata);
	@Nullable
	default Predicate<String> getExclusionFilter() {
		return null;
	}

}
String[] selectImports(AnnotationMetadata importingClassMetadata);

把需要加载的bean配置到数组中,springioc容器就会加载数组中配置好的bean,放入到ioc容器中。

10、为什么要使用@Import机制和开关类?

可以通过@ComponentScan+注解 和@Configuration+@Bean完成项目的开发和把项目中的bean加载到ioc容器中。为什么还要用@Import机制这种繁复的方式把bean通过实现ImportSelector接口,覆盖数组方法配置,让ioc容器去加载这些bean呢?

因为springboot特点:零配置;

因为提供的这些所谓机制能够很好的去把bean放入到ioc容器中。

在开发中,除了开发自己写的bean以外,还要初始化很多其他框架所提供的bean。比如:mybatis需要dataosoruce

<bean id="dataSource">bean>
<bean id="sqlSessionFactory" class="sqlsessionfactoryBean">
  <property name="datasource" ref="datasource"/>
bean>

仅仅使用@ComponentScan+注解 和@Configuration+@Bean也可以把第三方的bean初始化放入到ioc容器中去,但是==@ComponentScan+注解==默认情况下是根据当前的启动的类把作为入口进行bean查找。如果使用第三方那么就必须一个个去配置它的包。

@import作用:可以去灵活的加载第三方的starter配置类,自定义的配置类,以及官方提供的配置类。因为用这种机制,可以脱离当前项目的管控,通过这种机制把别人写的springboot的初始化好的配置类的bean,放入到自己的springboot工程中。比如:

 <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-webartifactId>
  dependency>
  <dependency>
      <groupId>org.projectlombokgroupId>
      <artifactId>lombokartifactId>
  <version>1.18.20version>
  dependency>
  <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-testartifactId>
  <scope>testscope>
  dependency>

11、springboot工程和项目找到/META-INF/spring.factories?

类加载 + 资源过滤 ,加载到map中 + cache中

真正具体的触发和执行@Import(AutoConfigurationImportSelector.class) 这个类中selectImports方法是在run方法中去执行调用的

启动主类方法

package com.example;

import com.example.importSelector.EnableUserCourse;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableUserCourse//自定义开关类
public class StudyBootsSourceApplication {

    public static void main(String[] args) {
        SpringApplication.run(StudyBootsSourceApplication.class, args);
    }

}

执行run方法

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
	return run(new Class<?>[] { primarySource }, args);
}

执行run方法重载

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
	return new SpringApplication(primarySources).run(args);
}
return (new SpringApplication(primarySources)).run(args);
# 拆解
// 初始化
SpringApplication application = new SpringApplication(primarySources)
// 运行阶段   
application.run();   
  • 初始化
  • 运行所有加载的bean放入ioc容器中

11.1 初始化

new SpringApplication(primarySources)

把springboot中含有/META-INF/spring.factories 的所有初始化接口监听器接口,以及它们对应下面的所有的实现子类全部抓取出来,放入对应位置其实就是map中即可。

通过类加载器去收集springboot中含有/META-INF/spring.factories配置文件,然后解析配置文件。然后放入到Map中。

11.1.1 调用构造函数方法
public SpringApplication(Class<?>... primarySources) {
    this((ResourceLoader)null, primarySources);
}
11.1.2 调用具体的初始化方法过程
 public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        // 1: 初始化数组,集合,开关标记
     	this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = Collections.emptySet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
        this.applicationStartup = ApplicationStartup.DEFAULT;
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
     
     	// 核心代码1
        this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
       // 核心代码2
        this.bootstrapRegi this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
       // 核心代码3
        this.bootstrapRegi this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }

核心代码都在调用一个相同的方法:

核心代码1

this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class)

核心代码2

this.getSpringFactoriesInstances(ApplicationContextInitializer.class);

核心代码3

this.getSpringFactoriesInstances(ApplicationListener.class)

三个都传递了一个类

原因:触发类加载器

作用:触发类加载器,通过双亲委派模型,把项目中所有的类,包括jdk、jdkext、target/classes、spring.jar、mybatis.jar,把他们中编译号的字节文件class找到,放入map中。

BootstrapRegistryInitializer

提前把项目中的类全部找到放入缓存map中,然后给ApplicationContextInitializer 、ApplicationListener 提供一个缓存机制,后面两者获取对应bean就不会重复触发类加载,频繁的扫描过滤。

11.1.3 调用具体的getSpringFactoriesInstances
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
	return this.getSpringFactoriesInstances(type, new Class[0]);
}
	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = this.getClassLoader();
        Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

类加载器:AppClassLoader – ExtClassLoader – BootstrapClassLoader(双亲委派模型)

  ClassLoader classLoader = this.getClassLoader();

双亲委派模型:找项目中所有的class字节文件,不论jdk、ext、项目写的classes、spring.jar全部找到。

在启动时,项目会调用类加载器通过双亲委派模型把项目中所有的classes全部找到。然后放入到jvm中去,只不过springboot把这些加载的classes进行过滤匹配把符合条件的bean放入到ioc容器中的过程。

过滤匹配:

  • 扫包 + 注解(@Service,@Controller)
  • 是不是符合import机制
  • 是不是符合@Configuration + @Bean

SpringBoot源码分析_第2张图片

11.1.4 对类加载的加载类进行过滤
  Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

type:interface org.springframework.boot.Bootstrapper 开始进行匹配过滤。

作用:加载缓存,把类加载中所有的jar文件存在:META-INF/spring.factories 文件中的内容全部找到。然后这个META-INF/spring.factories中的bean全部放入到Map中

11.1.5 找到jar包中包含MEAT-INF/spring.factories

private static Map loadSpringFactories(ClassLoader classLoader) {
Map result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();

        try {
            // 通过类加载器,把jar中包含MEAT-INF/spring.factories,找到
            // 原理:双亲委派模型:
            Enumeration urls = classLoader.getResources("META-INF/spring.factories");

            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                // 解析
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryTypeName = ((String)entry.getKey()).trim();
                    String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    String[] var10 = factoryImplementationNames;
                    int var11 = factoryImplementationNames.length;

                    for(int var12 = 0; var12 < var11; ++var12) {
                        String factoryImplementationName = var10[var12];
                        ((List)result.computeIfAbsent(factoryTypeName, (key) -> {
                            return new ArrayList();
                        })).add(factoryImplementationName.trim());
                    }
                }
            }

            result.replaceAll((factoryType, implementations) -> {
                return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
            });
            cache.put(classLoader, result);
            return result;
        } catch (IOException var14) {
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
        }
    }
}

11.2 springboot是如何把需要的bean加载出来的?

springBoot借鉴了java9的新特性:spi机制(把需要被加载类放入一个配置中)。

springboot命名规则:META-INF/spring.factories。

  • 这个文件中定义springboot所有的需要加载的bean。
  • 找到文件
  • 解析文件
  • 解析以后的bean,放入到map中(没有和springioc产生任何关系
11.2.1 找到第一个jar包进行解析
jar:file:/C:/Users/xuche/.m2/repository/org/springframework/boot/spring-boot/2.4.8/spring-boot-2.4.8.jar!/META-INF/spring.factories

SpringBoot源码分析_第3张图片

# Logging Systems
org.springframework.boot.logging.LoggingSystemFactory=\
org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory,\
org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory,\
org.springframework.boot.logging.java.JavaLoggingSystem.Factory

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
org.springframework.boot.context.config.StandardConfigDataLocationResolver

# ConfigData Loaders
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
org.springframework.boot.context.config.StandardConfigDataLoader

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor

# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.context.config.ConfigDataNotFoundFailureAnalyzer,\
org.springframework.boot.context.properties.IncompatibleConfigurationFailureAnalyzer,\
org.springframework.boot.context.properties.NotConstructorBoundInjectionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\
org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer

# Failure Analysis Reporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

SpringBoot源码分析_第4张图片

11.2.2 找到第二个jar进行解析
URL [jar:file:/C:/Users/xuche/.m2/repository/org/springframework/spring-beans/5.3.8/spring-beans-5.3.8.jar!/META-INF/spring.factories]
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
11.2.3 找到第三个jar进行解析

SpringBoot源码分析_第5张图片

# Auto Configure
org.springframework.boot.env.EnvironmentPostProcessor=\
  com.baomidou.mybatisplus.autoconfigure.SafetyEncryptProcessor
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
  com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

11.2.4 找到第四个jar进行解析(重点)
URL [jar:file:/C:/Users/xuche/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.4.8/spring-boot-autoconfigure-2.4.8.jar!/META-INF/spring.factories]
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

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

# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener

# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.data.redis.RedisUrlSyntaxFailureAnalyzer,\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.flyway.FlywayMigrationScriptMissingFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer,\
org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.session.NonUniqueSessionRepositoryFailureAnalyzer

# Template availability providers
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.servlet.JspTemplateAvailabilityProvider

org.springframework.boot.autoconfigure.EnableAutoConfiguration

SpringBoot源码分析_第6张图片

初始化阶段仅仅只是一个解析和准备的工作,把需要的bean全部找到。

ApplicationContextInitializers

org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
org.springframework.boot.context.ContextIdApplicationContextInitializer,
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

SpringBoot源码分析_第7张图片

ApplicationListeners

org.springframework.context.ApplicationListener=
org.springframework.boot.ClearCachesApplicationListener,
org.springframework.boot.builder.ParentContextCloserApplicationListener,
org.springframework.boot.context.FileEncodingApplicationListener,
org.springframework.boot.context.config.AnsiOutputApplicationListener,
org.springframework.boot.context.config.DelegatingApplicationListener,
org.springframework.boot.context.logging.LoggingApplicationListener,
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener,
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

11.3 运行加载

.run(args);

运行阶段,把初始化阶段的信息进行过滤和筛选,触发springioc提供的声明周期的机制,把符合条件的bean放入到ioc容器中。

当然这个过程还初始化其他信息:比如banner、日志、上下对象、应用参数接口、运行时run接口的调用等等。

selectorImport机制其实就是run方法这个阶段去触发执行,它会把初始化好的所有的符合条件的配置类,放入selectimport数组中,然后调用ioc初始化。

启动类在启动默认情况下,会把当前主类的包名作为的包入口

@ComponentScan的原理。

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer

证明:注解的解析和放入ioc是在运行阶段去执行和解析的

  • 在初始化的构造函数结束行打断点 — run方法开头打断点----在解析类中打断点

    如果按照这个执行的话,说明初始阶段仅仅就解析spring.factories这个文件和收集对应需要初始化的bean。

    并且证明注解的解析和bean初始化都是在run方法执行中

  • 在初始化的构造函数结束行打断点 -----在解析类中打断点(错误)

Run ----------> 1 2 3 4 5 6 7 -------- > selectImports

1、执行run方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kAXTQKZr-1628066330091)(C:\Users\长颈鹿\Pictures\springboot\源码分析\源码分析11.png)]

2、

this.refreshContext(context);

3、

 protected void refresh(ConfigurableApplicationContext applicationContext) {
        applicationContext.refresh();
    }

4、

 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
        if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }

5、

   invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
           

6、

  postProcessor.postProcessBeanDefinitionRegistry(registry);

7、ConfigurationClassPostProcessor

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	parser.parse(candidates);
}
public void processGroupImports() {
            Iterator var1 = this.groupings.values().iterator();

            while(var1.hasNext()) {
                ConfigurationClassParser.DeferredImportSelectorGrouping grouping = (ConfigurationClassParser.DeferredImportSelectorGrouping)var1.next();
                Predicate<String> exclusionFilter = grouping.getCandidateFilter();
                grouping.getImports().forEach((entry) -> {
                    ConfigurationClass configurationClass = (ConfigurationClass)this.configurationClasses.get(entry.getMetadata());

                    try {
                        ConfigurationClassParser.this.processImports(configurationClass, ConfigurationClassParser.this.asSourceClass(configurationClass, exclusionFilter), Collections.singleton(ConfigurationClassParser.this.asSourceClass(entry.getImportClassName(), exclusionFilter)), exclusionFilter, false);
                    } catch (BeanDefinitionStoreException var5) {
                        throw var5;
                    } catch (Throwable var6) {
                        throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configurationClass.getMetadata().getClassName() + "]", var6);
                    }
                });
            }

        }

        private Group createGroup(@Nullable Class<? extends Group> type) {
            Class<? extends Group> effectiveType = type != null ? type : ConfigurationClassParser.DefaultDeferredImportSelectorGroup.class;
            return (Group)ParserStrategyUtils.instantiateClass(effectiveType, Group.class, ConfigurationClassParser.this.environment, ConfigurationClassParser.this.resourceLoader, ConfigurationClassParser.this.registry);
        }
    }

SpringBoot源码分析_第8张图片

SpringBoot源码分析_第9张图片

11.4 如何和springioc发生关系

run方法执行:this.refreshContext(context);

11.5 Spring生命周期的阶段

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

        }
    }
this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var10) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
            }

            this.destroyBeans();
            this.cancelRefresh(var10);
            throw var10;
        } finally {
            this.resetCommonCaches();
            contextRefresh.end();
        }

    }
}

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