当前位置: 首页 > news >正文

Spring Boot 原理分析

spring-boot.version:2.4.3.RELEASE

Spring Boot 依赖管理

spring-boot-starter-parent

配置文件管理

<resources>
      <resource>
        <directory>${basedir}/src/main/resources</directory>
        <filtering>true</filtering>
        <includes>
          <include>**/application*.yml</include>
          <include>**/application*.yaml</include>
          <include>**/application*.properties</include>
        </includes>
      </resource>
      <resource>
        <directory>${basedir}/src/main/resources</directory>
        <excludes>
          <exclude>**/application*.yml</exclude>
          <exclude>**/application*.yaml</exclude>
          <exclude>**/application*.properties</exclude>
        </excludes>
      </resource>
    </resources>

spring-boot-dependencies

1.常用技术的版本号管理

<properties>
    <activemq.version>5.15.14</activemq.version> 

2.常用技术的依赖管理

<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-amqp</artifactId>
        <version>${activemq.version}</version>
      </dependency>

3.插件管理

<build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.codehaus.mojo</groupId>
          <artifactId>build-helper-maven-plugin</artifactId>
          <version>${build-helper-maven-plugin.version}</version>
        </plugin>

spring-boot-starter-web

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.3.7.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.3.7.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.3.7.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.12.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.12.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

Spring Boot 自动配置

由@SpringBootApplication配置springboot

源码:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration

@Configuration
public @interface SpringBootConfiguration {

说明是一个配置类,相当于XML配置文件

@EnableAutoConfiguration

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

@AutoConfigurationPackage

@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

        @Override
        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
        }

new PackageImports(metadata).getPackageNames().toArray(new String[0]):获取主程序启动类所在包

AutoConfigurationImportSelector.class中

有个方法getAutoConfigurationEntry()中

List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);:获取自动配置类

# 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,\

。。。。。。

configurations = getConfigurationClassFilter().filter(configurations);:选出符合当前项目的自动配置类

@ComponentScan

扫描主程序启动类所在包下的组件

Spring Boot 执行流程

SpringApplication.run(Springboot11Application.class, args);

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

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

由上面代码看出,程序会创建SpringApplication实例并初始化和调用run方法启动项目

SpringApplication实例并初始化

public SpringApplication(Class<?>... primarySources) {
        this(null, primarySources);
    }

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        this.webApplicationType = WebApplicationType.deduceFromClasspath();//判断web应用类型,servlet应用还是reactive应用
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置SpringApplication应用的初始化器
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//设置SpringApplication应用的监听器
        this.mainApplicationClass = deduceMainApplicationClass();//推断主程序启动类
    }

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;
    }

run方法

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);//获取监听器
        listeners.starting();//启动监听器

        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);// Create and configure the environment
            configureIgnoreBeanInfo(environment);//

            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            refreshContext(context);
            afterRefresh(context, applicationArguments);

            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
            callRunners(context, applicationArguments);//调用自定义的执行器,在启动项目后立即执行一些特定程序
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {

/**
     * Called immediately before the run method finishes, when the application context has
     * been refreshed and all {@link CommandLineRunner CommandLineRunners} and
     * {@link ApplicationRunner ApplicationRunners} have been called.
     * @param context the application context.
     * @since 2.0.0
     */
            listeners.running(context);//
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }

相关文章:

  • 打靶记录29——dawn
  • 红队视角出发的k8s敏感信息收集——持久化存储与数据泄露
  • 达梦:跟踪日志诊断
  • 备战蓝桥杯 Day2 枚举 Day3 进制转换
  • 2024 StoryDiffusion 文字/文字+图像----->视频
  • 系统不是基于UEFI的win11,硬盘格式MBR,我如何更改为GPT模式添加UEFI启动?
  • 【C++】RBTree(红黑树)模拟实现
  • 【第4章:循环神经网络(RNN)与长短时记忆网络(LSTM)— 4.4 文本分类与情感分析】
  • 【VB语言】EXCEL中VB宏的应用
  • vscode怎么更新github代码
  • 怎么理解 Spring Boot 的约定优于配置 ?
  • pg_sql关于时间的函数
  • npm运行Vue项目报错 error:0308010c:digital envelope routines::unsupported
  • 新用户冷启动阶段使用的推荐算法策略
  • 小红书图文笔记批量制作
  • C#上位机--基本数据类型
  • NoSQL数据库-体系框架
  • Android 系统Service流程
  • 使用 Python 爬虫获取微店商品详情 API 接口数据
  • 太速科技-509-U200E U250E 基于XCVU9P的4路QSFP28光纤PCIeX16收发卡
  • 中科院院士魏辅文已卸任江西农业大学校长
  • 计划招录2577人,“国考”补录8日开始报名
  • 中国驻俄大使张汉晖人民日报撰文:共襄和平伟业,续谱友谊新篇
  • Neuralink脑接设备获FDA突破性医疗设备认证
  • 山东滕州一车辆撞向公交站台致多人倒地,肇事者被控制,案件已移交刑警
  • 新华每日电讯:上海“绿色大民生”撑起“春日大经济”