SpringBoot的原理初步解析

运行原理的初步认识

我们之前写HelloSpringBoot,是怎样运行的那,Maven项目,我们从pom.xml文件开始吧。

pom.xml

父依赖

其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.0</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

在点进去,还有一个父依赖

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>3.1.0</version>
</parent>

这里才是真正管理springBoot应用里面所有依赖的地方,SpringBoot的版本控制中心;

以后我们导入依赖是不需要写版本;但是如果导入的包没有在依赖中管理就需要手动导入配置版本。

启动器:spring-boot-starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-xxx : 表示spring-boot的场景启动器

spring-boot-starer-web: 帮我们导入了web模块正常运行所依赖的组件;

SpringBoot将所有的功能场景都抽取出来,做成一个个的starer(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来,我们要用什么功能就导入什么样的场景启动器即可;我们未来也可以自己定义staretr;

主启动类

分析完了pom.xml文件现在我们来看看这个启动类

默认的主启动类

// @SpringBootApplication : 标注这个类是一个springboot的应用
@SpringBootApplication
public class HelloSpringBoot {
    public static void main(String[] args) {
        //将springboot应用启动
        SpringApplication.run(HelloSpringBoot.class, args);
    }

}

但是这个类一点都不简单! 让我们继续来分析

@SpringBootApplication

作用:标注某个类上表示这个类是SpringBoot的主要配置类,SpringBoot就应该运用这个类的main方法来启动springboot应用;

进入这个注解:可以看到上面还有其他注解!‘

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

@ComponentScan

这个注解在Spring中很重要,它对应XML配置中的元素。

作用:自动扫描并加载符合条件的组件或者bean,将这个bean定义到IOC容器中

@SpringBootConfiguration

作用:springboot的配置类,标注在某个类上,表示一个SpringBoot的配置类;

我们继续进入这个注解查看

//我们点击@Configuration注解得到下面的@Component

@Configuration

@Component


这里的@Configuration,说明这是一个配置类,配置类就是对spring的xml配置文件;

里面的@Component这说明,启动类本身也是spring中的组件而已,负责启动应用。

我们回到@SpringBootConfiguration注解中继续看。

@EnableAutoConfiguration

@EnableAutoConfiguration:开启自动配置功能

以前我们需要自己配置的东西,而现在springboot可以自动帮我们配置;

@EnableAutoConfiguration告诉springboot开启自动装配配置功能,作用自动装配才能生效。

点进注解继续查看:
@AutoConfigurationPackage :自动装配包

@Import({AutoConfigurationPackages.Registrar.class})
public @interface AutoConfigurationPackage {
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};
}

@Import:spring底层注解@import,给容器中导入一个组件

Registrar.class 作用:将主启动类的所有包及包下所有子包里面的所有组件扫描spring容器;

我们继续退回上一步,

@Import({AutoConfigurationPackages.Registrar.class}):给容器导入组件;

AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入那些组件的选择器 我们点击进去看这个类的源码:

1、这个类中有一个这样的方法


// 获得候选的配置
 protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
      //这里的getSpringFactoriesLoaderFactoryClass()方法
    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
    }
 
    

2、这个方法又调用了 SpringFactoriesLoader类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法

 public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        return forDefaultResourceLocation(classLoader).loadFactoryNames(factoryType);
    }

3、发现一个多次出现的文件:spring.factories,全局搜索它

spring.factories

我们根据源头打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在!

image-20230525110638549

我们在上面的自动配置类随便找一个打开看看,比如 :WebMvcAutoConfiguration

image-20230525111756018

这些一个个的都是JavaConfig配置类,而且都注入了一些bean可以找一下自己认识的类,熟悉一下!

所有,自动装配真正实现是从classpath中搜索所有META-INF/spring.factories配置文件,并将其中对应的rg.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类,然后将这些都汇总成一个实例化并加载到IOC容器中。

自动配置的流程图

image-20230525152038105

结论

1、springboot在启动的时候从类路径的META-INF/spring.factories中获取EnableAutoConfiguation指定的值

2、将这些值作为自动配置类导入容器,自动配置类就生效,帮我们进行自动配置工作;

3、整个JAVAEE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

4、它会給容器中导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件;

5、有了自动装配类,免去了我们手动编写配置注入功能组件等的工作;

springApplication

这是一个不简单的方法

刚刚开始我还以为只是一个简单的main方法,没想到却开启了一个服务器;

@SpringBootApplication
public class HelloSpringBoot {
    public static void main(String[] args) {
        //将springboot应用启动
        SpringApplication.run(HelloSpringBoot.class, args);
    }

}

SpringApplication.run分析

分析该方法主要分为两部,一是SpringApplication的实列化,二是run方法的执行;

SpringApplication

这个类主要做了以下四件事情:

  1. 推断应用的类型是普通项目还是web项目
  2. 查找并加载所有初始化器,设置到initiaizers属性中
  3. 找出所有的应用程序监听器,设置到listeners属性中
  4. 推断并设置main方法的定义类,找到运行的主类

查看构造器:

public class SpringApplication {
    public static final String BANNER_LOCATION_PROPERTY_VALUE = "banner.txt";
    public static final String BANNER_LOCATION_PROPERTY = "spring.banner.location";
    private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
    private static final Log logger = LogFactory.getLog(SpringApplication.class);
    static final SpringApplicationShutdownHook shutdownHook = new SpringApplicationShutdownHook();
    private static final ThreadLocal<SpringApplicationHook> applicationHook = new ThreadLocal();
}

run方法流程分析图

image-20230525142454420

ic final SpringApplicationShutdownHook shutdownHook = new SpringApplicationShutdownHook();
private static final ThreadLocal applicationHook = new ThreadLocal();
}


## run方法流程分析图

[外链图片转存中...(img-I8JOEOsU-1685159325246)]

=========大家可以自己根据图来理解一下=========
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值