面试题springboot启动流程_Spring boot面试

面试题springboot启动流程_Spring boot面试SpringBoot启动原理1、什么是SpringBoot2、SpringBoot启动原理3、三个关键注解解析3.1、@SpringBootConfiguration注解解析1、什么是SpringBootSpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,SpringBoot致力于在蓬勃发展的快速应用开发领域(RapidApplication

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

1、什么是SpringBoot

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(Rapid Application Development)成为领导者。

Spring大家都知道,Boot是启动的意思。所以,Spring Boot其实就是一个启动spring项目的一个工具而已。从最根本上来讲,Spring Boot就是一些库的集合,它能够被任意项目的构建系统所使用。

2、SpringBoot启动原理

SpringBoot启动整体可分为两步:

  • 初始化一个SpringApplication对象
  • 执行该对象的run()方法

想了解SpringBoot的启动原理,首先就要从项目的主启动类入手,说到主启动类那最关键的就是注解@SpringBootApplication

先看下SpringBoot主启动类:

@SpringBootApplication
public class HelloWorldApplication { 
   
    public static void main(String[] args) { 
   
        SpringApplication.run(HelloWorldApplication.class, args);
    }
}

再看下@SpringBootApplication注解的源码:

@Target({ 
   ElementType.TYPE})//注解的适用范围,其中TYPE用于描述类、接口(包括注解类型)或枚举类型
@Retention(RetentionPolicy.RUNTIME)//注解的声明周期,保留到class文件中(三个声明周期)
@Documented//表名这个注解应该被javadoc记录
@Inherited//表名子类可以继承这个注解
@SpringBootConfiguration//继承了@Configuration注解,表示当前类是注解类
@EnableAutoConfiguration//开启SpringBoot的自动注解功能,器主要借助@import注解实现的
@ComponentScan(excludeFilters = { 
   //扫描路径配置(具体使用待配置)
	@Filter(type = FilterType.CUSTOM, classes = { 
   TypeExcludeFilter.class}), 
	@Filter(type = FilterType.CUSTOM, classes = { 
   AutoConfigurationExcludeFilter.class})
	}
)
public @interface SpringBootApplication { 
   
	...
}

从上述我们可以看出,实际上@SpringBootApplication是一复合的注解,其中起到主要作用的注解是:

  • SpringBootConfiguration:继承了@Configuration注解,表示当前类是注解类
  • @EnableAutoConfiguration:开启SpringBoot的自动注解功能,器主要借助@import注解实现的
  • @ComponentScan:扫描路径配置(具体使用待配置)

所以我们把主启动类上面的注解写成这三个注解组合的形式其实也是可以的,整个SpringBoot应用依然可以与之前的启动类功能一样:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { 
   
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public class HelloWorldApplication{ 
   
    public static void main(String[] args) { 
   
        SpringApplication.run(HelloWorldApplication.class, args);
    }
}

因为如果我们每次新建项目时都要写上这三个注解来完成配置,这显然太繁琐了,SpringBoot就为我们提供了@SpringBootApplication这样一个复合注解来简化我们的操作。

3、三个关键注解解析

3.1、@SpringBootConfiguration注解解析

我们看下@SpringBootConfiguration注解的源码

@Target({ 
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration { 
   
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

@SpringBootConfiguration标注在哪个类上说明这是一个主配置类。
SpringBoot为了区别@Configuration而提供新的专属于SpringBoot的注解SpringBootConfiguration,在上面我们可以看出SpringBootConfiguration其实也是基于@Configuration注解实现的, 配置类也是容器中的一个组件;@Component,而它本身也是Spring容器中的一个配置。

其实了解到这,我们把SpringBoot的启动类来拆成两个类,拆完以后就非常清楚了:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class HelloWorldConfiguration { 
   

}
public class HelloWorldApplication { 
   
    public static void main(String[] args) { 
   
        SpringApplication.run(HelloWorldConfiguration .class, args);
    }
}

从上面拆分后我们可以很清晰的看出,其实启动类HelloWorldApplication就是一个标准的StandAlone(独立)类型的Java程序main函数启动类。

3.2、@EnableAutoConfiguration 注解解析

看到这我想大家肯定就一下想起了Spring中很多以@Enable开头的注解,比如:@EnableScheduling:自动调度@EnableCaching:自动缓存以及@EnableMBeanExport:监控JVM运行时状态等等。

@EnableAutoConfiguration:开启自动注解的理念和工作原理和他们是一脉相承。简单的来说该注解是借助@Import注解的支持来实现的,Spring的IoC容器会收集和注册特定场合相关的Bean实例:

  • @EnableScheduling自动调度:是通过@import将Spring调度框架相关的Bean都加载到IoC容器中。
  • @EnableMBeanExport监控JVM运行时状态是通过@Import将JMX相关的Bean定义加载到IoC容器中。
  • @EnableAutoConfiguration开启自动注解:是通过@Import将所有复合配置条件的Bean定义加载到IoC容器中,仅此而已。

我们看下@EnableAutoConfiguration注解的源码:

@Target({ 
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({ 
   ![AutoConfigurationImportSelector.class](https://img-blog.csdnimg.cn/72fda74967224245a0028a2b4552a271.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5LiA5a6_5ZCb,size_20,color_FFFFFF,t_70,g_se,x_16)})
public @interface EnableAutoConfiguration { 
   
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

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

    String[] excludeName() default { 
   };
}

上述源码的注解中,最关键的@EnableAutoConfiguration 主要就是借助AutoConfigurationImportSelector.class来帮助SpringBoot应用将所有符合条件的@Configuration标注的配置类都加载到当前SpringBoot创建并使用的IoC容器中,就像一个收割机一样,全文搜索配置类:

在这里插入图片描述

我们可以看下AutoConfigurationImportSelector.class类的部分源码:

public class AutoConfigurationImportSelector implements 
DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { 
   

	protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() { 
   
        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
    }
    
    protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() { 
   
        return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader);
    }
}

从上面我们可以看出,@AutoConfiguration注解主要是借助于SpringFactoriesLoader工厂加载类,获取配置类的过滤器监听器都是通过SpringFactoriesLoader来实现的,那下面让我们来看下什么是SpringFactoriesLoader:

3.3、SpringFactoriesLoader(幕后英雄)

SpringFactoriesLoader属于Spring框架专属的一种扩展方案,其功能和使用方式类似于Java的SPI方案:java.util.ServiceLoader,它的主要功能就是从指定的配置文件META-INF/spring.factories中加载配置,spring.factories是一个非常经典的java.properties文件,内容格式是key-value形式,只不过这key以及value都非常特殊,为Java类的完整类名和包名,(Fully qualified name),比如:

com.wbs.service.DemoService = com.wbs.service.impl.DemoServiceImpl

然后Spring框架就可以根据某个类型作为Key来查找对应的类型名称列表了,SpringFactories源码如下:

public final class SpringFactoriesLoader { 
   
    public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
    
    private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
    
    static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap();
}

对于@EnableAutoConfiguration来说,SpringFactoriesLoader的用途和其本意稍有不同,他本意是为了提供SPI扩展,而在@EnableAutoConfiguration场景下,它更多的是提供一种配置查找的功能的支持,也就是根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为key来获取一组对应的@Configuration类:

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

在SpringBoot的AutoConfiguration依赖包中的META-INF文件下的spring.factories文件中,我们可以找到以上内容,这就很好的解释了为什么。

总结来说,@EnableAutoConfiguration能实现自动配置的原理就是:SpringFactoriesLoader从classpath类路径下去搜寻所有的META-INF/spring.factories文件,并将其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的Value配置项通过反射的方式实例化为对应的标注为@Configuration的JavaConfig形式的IoC容器配置类,然后汇总到当前使用的IoC容器中。

3.4、@ComponentScan 注解解析

@ComponentScan注解很重要,它对应XML配置中的元素,@ComponentScan的功能就是自动扫描并加载符合条件的组件(如@Component和@Repository)Bean定义,最终将这些Bean定义加载到当前使用的IoC容器中。

我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认spring框架实现会从声明@ComponentScan所在类的package进行递归扫描。


在这里插入图片描述

一起学编程,让生活更随和!如果你觉得是个同道中人,欢迎关注博主公众号:【随和的皮蛋桑】。专注于Java基础、进阶、面试以及计算机基础知识分享?。偶尔认知思考、日常水文?。

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196382.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • git clone下来的代码放在哪里,如何放在指定路径

    git clone下来的代码放在哪里,如何放在指定路径今天从github上clone了代码,最后出来形如:但是话说我的东西下载到哪里去了呢????摸不着头脑,然后百度之,发现一般会放在命令行对应的路径下,也就是win+R&gt;cmd查看命令行地址:然后去此路径下寻找之,果然在这里。那么,如何才能clone到自己指定的路径下呢?百度之得如下说法:gitclonehttps://github.com/jque…

  • 如何从jdbc中获取数据库建表语句信息(表字段名称/表字段类型/表字段注释信息/表字段长度等等)

    如何从jdbc中获取数据库建表语句信息(表字段名称/表字段类型/表字段注释信息/表字段长度等等)*如何从jdbc中获取数据库建表语句信息(表字段名称/表字段类型/表字段注释信息/表字段长度等等)*1,表字段名称*2,表字段类型*3,表字段注释信息这里介绍3种方式,如下:第一种方式:执行sql语句获取select*fromuser_pop_infowhere1=2第二种方式:执行sql语句获取showcreatetableuser_pop_info第二种方式:直接从jdbc数据库连接Connection实例中获取三种方式获取的数据有一些区…

  • idea设置注解格式_idea添加类注释

    idea设置注解格式_idea添加类注释开发过程中经常看到源码中的注释,感叹大佬的注释为何写得那么清新脱俗,决定简单研究一下IDEA中的注释本文主要分为三个部分:注释的显示状态切换如何在注释中添加超链接注释状态切换:之前看大佬们的注释都是:而我的注释:为何源码中别人的注释和自己写的注释显示效果完全不一样呢其实是设置问题而已(今天才知道…尴尬了)点击图中的铅笔就可以切换为注解源码,效果如下:再点击图中左上角的图标就切换回了注释的阅览视图…

  • 2023考研高数接力题典1800习题讲解

    2023考研高数接力题典1800习题讲解第一部分(函数、极限、连续)极限求法:①直接代入数值②约去不能代入的零因子③分子分母同除最高次幂④分子分母有理化⑤公式法⑥等价无穷小量的代换⑦洛必达法则⑧换底公式(对数)入门练习填空题讲解(1~4):第一题:我们通过观察,发现是0/0型的,自然想到了洛必达法则。百度百科:洛必达法则是在一定条件下通过分子分母分别求导再求极限来确定未定式值的方法。众所周知,两个无穷小之比或两个无穷大之比的极限可能存在,也可能不存在。因此,求这类极限时往往需要适当的变形,转化成可利用极限运算法则或重要

  • 《关于VirtualBox在桥接模式下无法联网 解决方案》

    《关于VirtualBox在桥接模式下无法联网 解决方案》博主遇到了这个问题,百度了大半天还是没有解决到,可能是由于下面链接的文章的标题关键词比较偏,很难精确的定位到此文章,于是博主就决定总结归纳了一下,希望对大家有所帮助。。经过无数次的百度,早已厌倦粘贴党,问牛答马党,错误党,大大的浪费了大家的时间,于是博主开了这篇文章..我们在VBOX上面安装了Linux之后,VBOX默认网络设置是使用NAT模式的,这种方式宿

  • QGIS 3.0 使用教程

    QGIS 3.0 使用教程网易云课堂:https://study.163.com/course/courseMain.htm?courseId=1005249002&utm_campaign=commission&utm_source=cp-400000000343054&utm_medium=share课程中所需要的数据和地图服务地址从这里下载:链接:https://pan…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号