SpringBoot源码分析篇一

SpringBoot源码分析篇一

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.7.1version>
parent>

SpringApplication认知

基本介绍

此类可以用来引导和发起一个源于Java main()方法的Spring应用。默认执行以下步骤引导应用:

1、 创建适当的 ApplicationContext 实例(依赖于classpath)

2、 注册 CommandLinePropertySource 来暴露命令行参数作为Spring属性

3、 刷新应用上下文,加载所有单例Bean

4、 触发所有 CommandLineRunner Bean

属性介绍

// "banner.txt" 默认banner位置
public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;

// "spring.banner.location" banner属性key
public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;

// 无关紧要,不用关注
private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";

// logging 日志
private static final Log logger = LogFactory.getLog(SpringApplication.class);

// shutdown 钩子
// 用来作为Spring Boot应用shutdown的钩子执行优雅的shutdown的执行器。此钩子追踪已注册的应用上下文以及通过	SpringApplication.getShutdownHandlers() 注册的任何操作。
static final SpringApplicationShutdownHook shutdownHook = new SpringApplicationShutdownHook();

// 主要源
private Set<Class<?>> primarySources;

// 来源
private Set<String> sources = new LinkedHashSet<>();

// 主应用类
private Class<?> mainApplicationClass;

// banner输出位置,默认控制台
private Banner.Mode bannerMode = Banner.Mode.CONSOLE;

// 日志启动信息 
private boolean logStartupInfo = true;

// 添加命令行属性
private boolean addCommandLineProperties = true;

// 添加转换Service
private boolean addConversionService = true;

// banner
private Banner banner;

// 资源加载器
private ResourceLoader resourceLoader;

// Bean 名生成器
private BeanNameGenerator beanNameGenerator;

// 配置环境
private ConfigurableEnvironment environment;

// web 应用类型,none、servlet[通常是这个]、reactive
private WebApplicationType webApplicationType;

// 无头  不关注
private boolean headless = true;

// 注册 shutdown 钩子
private boolean registerShutdownHook = true;

// 应用上下文初始化器
private List<ApplicationContextInitializer<?>> initializers;

// 应用监听器
private List<ApplicationListener<?>> listeners;

// 默认属性
private Map<String, Object> defaultProperties;

// 引导注册初始化器
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;

// 应用属性
private Set<String> additionalProfiles = Collections.emptySet();

// 允许bean定义覆盖
private boolean allowBeanDefinitionOverriding;

// 允许循环引用
private boolean allowCircularReferences;

// 自定义环境
private boolean isCustomEnvironment = false;

// 懒初始化
private boolean lazyInitialization = false;

// 环境前缀
private String environmentPrefix;

// 应用上下文工厂
private ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;

// 应用启动器
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;

构造方法分析

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    // 来源加载器,这里为null
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    // 主要来源[当前启动类]
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    // 从类路径推断应用类型
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers = new ArrayList<>(
        getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}
item1 推断应用类型分析
static WebApplicationType deduceFromClasspath() {
    // ClassUtils.isPresent 确定类是否可被加载
   if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
         && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
      return WebApplicationType.REACTIVE;
   }
   // 	private static final String[] SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet","org.springframework.web.context.ConfigurableWebApplicationContext" };
   for (String className : SERVLET_INDICATOR_CLASSES) {
      if (!ClassUtils.isPresent(className, null)) {
         return WebApplicationType.NONE;
      }
   }
   return WebApplicationType.SERVLET;
}
item2 获取Spring工厂实例【非常重要】
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;
}

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