Spring Boot-HelloWorld运行原理

✨【一心同学】的写作风格:喜欢用【通俗易懂】的文笔去讲解每一个知识点,而不喜欢用【高大上】的官方陈述。

✨【一心同学】博客的领域是【面向后端技术】的学习,未来会持续更新更多的【后端技术】以及【学习心得】。

✨如果有对【后端技术】感兴趣的【小可爱】,欢迎关注一心同学】💞💞💞

❤️❤️❤️**感谢各位大可爱小可爱!**❤️❤️❤️


目录

1.pom.xml

1.1父依赖

1.2启动器

2.主程序类@SpringBootApplication分析

2.1介绍

2.2@SpringBootConfiguration

2.2.1@Configuration

2.3@EnableAutoConfiguration

2.3.1@AutoConfigurationPackage

2.3.2@Import({AutoConfigurationImportSelector.class})

spring.factories

2.4@ComponentScan

3.SpringApplication

3.1 SpringApplication职责

3.2 run方法执行流程分析

结语


1.pom.xml

=============

1.1父依赖


org.springframework.boot

spring-boot-starter-parent

2.6.0

我们点击进去探以下究竟。

发现里面还有依赖一个父项目

org.springframework.boot

spring-boot-dependencies

2.6.0

我们继续把代码一层一层剥掉,继续点击进去往里面探究

果真!发现了一个宝藏!

<activemq.version>5.16.3</activemq.version>

<antlr2.version>2.7.7</antlr2.version>

<appengine-sdk.version>1.9.92</appengine-sdk.version>

<artemis.version>2.19.0</artemis.version>

<aspectj.version>1.9.7</aspectj.version>

<assertj.version>3.21.0</assertj.version>

<atomikos.version>4.0.6</atomikos.version>

<awaitility.version>4.1.1</awaitility.version>

<build-helper-maven-plugin.version>3.2.0</build-helper-maven-plugin.version>

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

问题:为什么用SpringBoot有的依赖需要写版本号,有的不需要写?

答案:

因为我们项目的pom里引入了parent节点,所以将最终的spring-boot-dependencies-2.6.0.pom也继承过来,而spring-boot-dependencies-2.6.0.pom里面管理了大部分的jar包的版本,所以我们依赖jar包的时候无需写版本号;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;

我们回过头去看我们注入的另一个依赖

org.springframework.boot

spring-boot-starter-web

是否发现在这个依赖中就不需要我们写版本号,因为在父节点中已经管理了这个jar包的版本,我们去spring-boot-dependencies-2.6.0.pom查看是否有管理这个jar包

果然,这个jar包有被SpringBoot所管理,所以不需要我们写配置文件。

问题:为什么启动main函数就能访问url?

答案:因为SpringBoot内嵌了一个tomcat。

1.2启动器


org.springframework.boot

spring-boot-starter-web

分析:

springboot-boot-starter-xxx:就是spring-boot的场景启动器

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

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

2.主程序类@SpringBootApplication分析

==============================

@SpringBootApplication

public class SpringBootIdeaApplication {

public static void main(String[] args) {

SpringApplication.run(SpringBootIdeaApplication.class, args);

}

}

2.1介绍


@SpringBootApplication: 标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

我们来分析@SpringBootApplication这个注解到底做了什么?

点击进入@SpringBootApplication查看:

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

//…

}

看到这么多注解,不要慌,其实这里面只有三个关键的注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

我们来对这三个注解一一进行讲解,看下这三个注解到底做了什么?

2.2@SpringBootConfiguration


介绍:SpringBoot配置类。标注在某个类上,表示这是一个SpringBoot的配置类

我们进入这个注解进行查看:

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Configuration

@Indexed

public @interface SpringBootConfiguration {

@AliasFor(

annotation = Configuration.class

)

boolean proxyBeanMethods() default true;

}

2.2.1@Configuration

@Configuration:说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件,也是一个组件(因为内部标注了@Component注解);

为了验证其也是一个组件,我们继续进入@Configuration的源码进行查看,看下是否有@Component注解。

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Component

public @interface Configuration {

@AliasFor(

annotation = Component.class

)

String value() default “”;

boolean proxyBeanMethods() default true;

}

果然看到了@Component ,这就说明该配置类也是容器中的一个组件,负责启动应用!

2.3@EnableAutoConfiguration


介绍:开启自动配置功能,那么以前我们需要配置的东西,Spring Boot帮我们自动配置,再也不需要写一堆繁琐的配置文件。

我们点击进去查看代码:

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@AutoConfigurationPackage

@Import({AutoConfigurationImportSelector.class})

public @interface EnableAutoConfiguration {

String ENABLED_OVERRIDE_PROPERTY = “spring.boot.enableautoconfiguration”;

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

String[] excludeName() default {};

}

发现里面有两个重要的注解:

  • @AutoConfigurationPackage
  • @Import({AutoConfigurationImportSelector.class})

2.3.1@AutoConfigurationPackage

源码分析:

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Inherited

@Import({Registrar.class})

public @interface AutoConfigurationPackage {

String[] basePackages() default {};

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

}

分析

@Import({Registrar.class}):给Spring容器中导入了Registrar组件

作用:将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器。

2.3.2@Import({AutoConfigurationImportSelector.class})

作用:快速给容器中导入一些组件。

AutoConfigurationImportSelector:

介绍导入哪些组件的选择器。

作用将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。

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

我们去查看一下它会导入哪些组件的选择器,进入AutoConfigurationImportSelector源码进行分析一下。

(1)该类有这样一个方法:

protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {

List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

Assert.notEmpty(configurations, “No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.”);

return configurations;

}

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

public static List loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {

ClassLoader classLoaderToUse = classLoader;

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

部分内容:

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注
止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

[外链图片转存中…(img-T1hIrIUU-1721154090709)]

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

[外链图片转存中…(img-hrw37fFv-1721154090710)]

部分内容:

[外链图片转存中…(img-l36NgRjN-1721154090711)]

[外链图片转存中…(img-4NwBruYn-1721154090711)]

[外链图片转存中…(img-o6Df1jD7-1721154090712)]

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值