1. 简述

Springboot启动是通过Application启动类实现

@SpringBootApplication(
    exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class},
    scanBasePackages = {"com.test.data"})
@EnableCaching
public class DataApplication {
  public static void main(String[] args) {
    SpringApplication.run(DataApplication.class); 
  }
}

springboot启动分为注解启动方法两个过程

2. @SpringBootApplicaiton注解

进入@SpringBootApplication注解内,可见@SpringBootApplication=@SpringCofiguration+@EnableConfiguration+@ComponentScan

@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 {...}

2.1 @SpringBootConfiguration -- Spring IOC容器配置类

进入@SpringBootConfiguration注解内如下,可见@SpringBootConfiguration本身也是一种配置(@Configuration)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {

@Configuration的作用(定义一些可以被自动加载IOC容器的配置bean):

@Configuration标注在类上,配置spring容器(应用上下文)。进入@Configuration注解里使用@Component,返回类型都会直接注册为bean(任何一个标注了@Bean的方法,其返回值都将作为一个bean定义注册到Spring的IOC容器),所以@Configuration具有和@Component作用,因此@CompoenntScan都能处理@Configuration注解的类

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

 

demo如下,使用@Configuration可以将配置文件中配置信息(比如下例中启动环境env 邮件收件人 emailTo等)作为元素组成的bean,在spring启动时自动注入到IOC容器中。

@Configuration
@Data
public class EmailConfig {

  @Value("${spring.profiles.active}")
  public String env;

  @Value("${email.to}")
  public String emailTo;

  @Value("${email.from}")
  public String emailFrom;
}

 

 

 

2.2 @EnableAutoConfiguration--(开启自动配置,使用@import將所有符合自动配置条件的bean定义加载到IOC容器)

进入@EnableAutoConfiguration如下,使用@Import将所有满足条件的bean自动加载到IOC容器

 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {...}

 

 

2.3 @ComponentScan-(开启自动自动扫描,默认扫描SpringApplication的run方法里的class所在的包路径下文件)

 自动扫描并加载符合条件的组件或者bean定义。默认扫描SpringApplication的run方法里class所有的包路径下文件

 

3.启动方法 .run() 

启动方法分为创建springApplicaiton实例执行run方法

3.1创建SpringApplication实例

SpringApplication实例创建过程如下图所示。

 

 

3.2 执行run()方法

包括环境准备、创建IOC容器、配置IOC容器基本信息、刷新上下文信息等。具体查看参考 https://www.cnblogs.com/enhance/p/17024932.html

public ConfigurableApplicationContext run(String... args) {
        long startTime = System.nanoTime();
        DefaultBootstrapContext bootstrapContext = createBootstrapContext();
        ConfigurableApplicationContext context = null;
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            configureIgnoreBeanInfo(environment);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
            }
            listeners.started(context, timeTakenToStartup);
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, listeners);
            throw new IllegalStateException(ex);
        }
        try {
            Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
            listeners.ready(context, timeTakenToReady);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

 

 

参考文献:

https://www.cnblogs.com/taojietaoge/p/16075820.html

https://www.cnblogs.com/dingjiaoyang/p/15513425.html

posted on 2022-12-17 11:44  colorfulworld  阅读(4385)  评论(0编辑  收藏  举报