小工具知识网

当前位置: 首页 > 行业知识 > SpringBoot底层原理

行业知识

SpringBoot底层原理

2026-10-30 13:32:00 来源:互联网转载

SpringBoot底层原理

一 配置优先级

1.配置方式

Springboot中支持三种配置方式,分别为:

  • application.properties
  • application.yml
  • application.yaml

    2.配置优先级

    当存在多份配置文件时,配置文件会按照它们的优先级生效。

    优先级从高到底分别为:application.peoperties>application.yml>application.yaml

    目前 application.yml 是最主流的方式

    3.其他配置方式

    Springboot除了以上常见的三种配置方式之外,还支持Java系统属性配置和命令行参数配置。

    1.Java系统属性配置示例

    # 在 java 命令后使用 —D 命令,然后书写需要配置的属性即可# 示例中配置了项目的运行端口为8081,即server.port=8081java -Dserver.port=8081 -jar [packageName].jar

    2.命令行参数配置示例

    # 在jar包名称之后,使用双横杠(--),后面紧跟配置的参数即可java -jar [packageName].jar --server.port=8082

    二 Bean管理

    1.获取bean对象

    默认情况下,Springboot项目在启动时会自动创建bean,并且将这些bean都存放在IOC容器中。

    如果想手动获取这些bean,则可以通过以下几种示例。

    首先需要注入ApplicationContext对象。

    在 Spring框架中,ApplicationContext是一个接口,代表了Spring容器,它负责管理Spring应用程序中所有的bean,同时提供了一些方法来获取Bean,注册Bean,是整个Spring应用的核心。

    默认情况下,一个Bean的名称是它的类名名称,然后将首字母小写。

    例如 DeptController,它在IOC容器中的默认名称为 deptController

    @Autowiredprivate ApplicationContext applicationContext;@Testvoid test1(){    //1.根据bean的名称来获取bean对象    EmpServiceImpl empServiceImpl1= (EmpServiceImpl) applicationContext.getBean("empServiceImpl");    System.out.println(empServiceImpl1);        //2.根据bean的类型来获取bean对象    EmpServiceImpl empServiceImpl2= applicationContext.getBean(EmpServiceImpl.class);    System.out.println(empServiceImpl2);        //3.根据bean的类型和名称来获取bean对象    // 以下方法和示例,在bean的默认名称被修改且有多个同类型的bean时,尤为有用。    EmpServiceImpl empServiceImpl3= applicationContext.getBean("empServiceImpl",EmpServiceImpl.class);    System.out.println(empServiceImpl3);}

    运行以上示例,可以看出,bean在IOC容器中,默认是单例存在的。

    如果想要实现每次使用时都是一个新的bean,则需要通过bean的作用域来进行配置。

    2.bean的作用域

    在Spring中,bean支持五种作用域,后三种在web环境下才能生效。

    默认情况下,Bean对象在项目启动时就会默认实例化。如果不希望在项目启动时就初始化,可以使用@Lazy注解,让Bean对象延迟初始化,直到第一次使用该Bean时才会进行初始化。

    @Service@Lazypublic class EmpServiceImpl extends ServiceImpl implements EmpService{    //code...}

    设置Bean的作用域,则需要通过@Scope注解来实现。

    以下示例中,我们将Bean的作用域设置为 prototype,即每次使用该Bean时都会创建新对象。

    @Service@Scope("prototype")public class EmpServiceImpl extends ServiceImpl implements EmpService{    //code...}

    现在再次运行前边获取Bean对象的代码示例,可以发现,三次获取到的Bean对象,已经不是同一个。

    3.声明第三方bean

    如果要申明的Bean来自第三方,是无法通过@Component及衍生注解来申明的,这个时候就需要使用@Bean注解。

    以 SAXReader 类为例,创建一个返回值为SAXReader对象的方法,方法名称就是以后被ICO管理的Bean对象名称。

    //将方法的返回值交给IOC容器管理,称为IOC容器的Bean对象@Beanpublic SAXReader saxReader(){    return new SAXReader();}

    在以后需要用到 SAXReader 对象的时候,直接注入即可,不用去实例化。

    @Autowiredprivate SAXReader saxReader;@Testvoid test2() throws DocumentException {    Document document = saxReader.read("xxx");}

    注意:一般情况下,我们通常会将所有需要申明的第三方bean对象统一放在一个配置类中,这样更加方便维护。

    @Configurationpublic class BeanAutoConfig {    // 可以通过@Bean注解的 name /value 属性来定义bean的名称    // 默认情况下,bean的名称就是方法名    @Bean    public RestTemplate restTemplate(){        return new RestTemplate();    }    }

    在声明第三方bean对象时,如果需要进行依赖注入,则只需要指定方法形参即可。Spring会根据类型进行自动装配。

    // EmpServiceImpl对象是要注入的bean对象@Beanpublic RestTemplate restTemplate(EmpServiceImpl empServiceImpl){    empServiceImpl.[xxx];    return new RestTemplate();}

    三 Springboot原理

    1.Springboot起步依赖

    Springboot整合了以前web开发需要用的一些依赖项,目前使用Springboot开发web项目,只需要引入 spring-boot-start-web 依赖即可。

    归根结底,SPringboot起步依赖的原理就是maven的依赖传递。

    2.自动配置

    当Springboot项目启动后,Springboot中的一些配置类,bean对象就会自动存入到IOC容器中,不需要我们手动去申明。从而简化了开发,省去了繁琐的配置。

    3.管理第三方包中的Bean

    1.配置实现方式1:@ComponentScan 组件扫描

    在启动类上使用 @ComponentScan注解,重新配置包扫描路径。@ComponentScan的basePackages参数支持数据格式,当有多个第三方包时,可使用数组形式申明。

    @ComponentScan(basePackages = "xxx1")

    或

    @ComponentScan(basePackages = {   "xxx1",   "xxx2"})

    注意:使用@ComponentScan申明时,当前Springboot项目中的包路径也必须包含在内,否则当前项目中的bean将会被无法识别。

    缺点:当项目较大时,引入大量的第三方依赖,此时启动类将会显得臃肿。

    2.配置实现方式2:@Import 组件导入

    使用@Import导入的类会被Spring加载到容器中。可以导入普通类,配置类,以及 ImportSelector 接口的实现类,支持数组。

    @Import({xx1.class,xx2.class})

    实现ImportSelector 接口,这里最核心的就是 selectImports方法,它返回了需要创建Bean对象的全部类。

    public class MyImportSelector implements ImportSelector {    @Override    public String[] selectImports(AnnotationMetadata importingClassMetadata) {        //此处的数组内容为需要导入的Bean对象的全类名,有多少写多少        return new String[]{"springboot.demo.GoodStudent"};    }}

    然后在启动类上使用@Import注解即可。

    @Import({MyImportSelector.class})

    单纯使用 @Import接口声明第三方Bean,缺点很明显。

    3.配置实现方式3:第三方依赖提供注解

    实际项目中,具体第三方依赖需要导入哪些Bean,只有第三方依赖自己知道。所以可以由第三方依赖提供注解,然后在项目中引入即可。

    此类型注解一般均由 Enable 开头,原理是在自定义注解中封装 @Import 注解。

    示例:

    @Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Import({        MybatisPlusConfig.class,        CorsConfig.class,        SpringWebConfig.class,        BeanAutoConfig.class,        RedisConfig.class})public @interface EnableShawnConfig {    }

    在第三方依赖包中定义一个EnableShawnConfig注解,然后使用 @Import将需要配置的Bean对象都引入进来。最后再在项目中使用该注解即可。

    @EnableShawnConfig@SpringBootApplicationpublic class ShawnServerSystemApplication {    public static void main(String[] args) {        SpringApplication.run(ShawnServerSystemApplication.class, args);    }}

    4.自动配置原理分析

    Springboot核心注解:@SpringBootApplication

    @SpringBootApplication下的重要注解:

    • @SpringBootConfiguration:申明当前注解也是一个配置类,因为@SpringBootConfiguration中也申明了@Configuration注解。所以可以直接在启动类中申明第三方的bean对象。
    • @EnableAutoConfiguration:Springboot自动配置的核心注解,它声明了@Import(AutoConfigurationImportSelector.class),AutoConfigurationImportSelector是ImportSelector接口的实现类,实现了 selectImports 方法。selectImports 方法返回了需要创建Bean对象的全部信息。
    • @ComponentScan:组件扫描,默认扫描当前引导类及其所在的子包。

      自动配置最核心的注解就是@EnableAutoConfiguration,由源码可知,selectImports 方法会读取一个固定目录下后缀名为.imports的文件。

      protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {    List configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())            .getCandidates();    Assert.notEmpty(configurations,            "No auto configuration classes found in "                    + "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "                    + "are using a custom packaging, make sure that file is correct.");    return configurations;}

      springboot3.x中,META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中,配置了需要创建Bean对象的全类名

      在Springboot2.x中,是通过两个关键文件来读取配置好的全类名的。

      spring.factories 是早起Springboot版本中自动配置的文件,在后续版本中已经逐渐不再使用。

      5.@Conditinal注解

      @Conditinal注解的作用:按照一定的条件判断,在满足条件后才会注册对应的Bean对象到IOC容器中

      它可以作用在类和方法上。

      @Conditinal本身是一个父级注解,它衍生除了很多子级注解

      • @ConditionalOnClass:判断环境中是否存在字节码文件,有则注册bean对象到IOC容器
      • @ConditionalOnMissingBean:判断环境中有没有对应的Bean(根据类型和名称),没有则注册Bean对象到IOC容器
      • @ConditionalOnProperty:判断配置文件中是否有对应属性和值,有则注册bean对象到IOC容器

上一篇:郑州网站建设怎么优化自己的网站

下一篇:怎么进行存款账户备案申请