首页 > 其他分享 >SpringBoot中怎么定义一个stater?自动装配规则到底是怎么的?

SpringBoot中怎么定义一个stater?自动装配规则到底是怎么的?

时间:2024-11-01 16:18:58浏览次数:5  
标签:怎么 SpringBoot spring 配置 boot autoconfigure stater bean factories

问题引出

最近实习发现公司项目中有spring.factories文件,是用来定义starter的,让这个模块可以被其他模块引入pom依赖后直接使用,那为什么还必须用spring.factories配置才能被其他模块使用,直接引入依赖不能直接使用吗?

答案是能用,但是只能使用这个模块中的非Bean,也就是非spring容器中的类(例如工具类的静态方法)。这个模块定义的spring Bean不能用,会报找不到该Bean的错误,也就是扫描不到该模块中定义的Bean,比如下面例子:

在demo模块中直接使用starter模块的server1和server2两个bean,会报错:

为什么扫描不到?

SpringBoot默认扫包规则:在不自己定义scanBasePackage参数或scanBasePackageClasses参数或@ComponentScan扫包规则下,SpringBoot默认约定只会默认扫描主程序包下及其子包下的bean

所以,你通过pom引入的第三方依赖,人家定义的包结构大概率和你的包结构不一样(包结构一般都是公司内部自定义的)。所以,依赖引入来的Bean就扫描不到!自然也就找不到该Bean。

使用@ComponentScan注解把所有包都列举出来,如果引入的依赖多了,显然不太现实。

那怎么办呢?怎么定义一个让别人直接能使用的stater呢?

starter怎么写

参考spring-boot-autoconfigure这个包的规则(其实这个包加上@SpringBootApplication注解就是springboot的自动装配原理): 

1. 添加spring-boot-stater依赖(因为这个依赖里有spring-boot-autoconfigure这个依赖):

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

2.定义configuration类,在里面创建需要的bean:

3.在resource目录下新建目录META-INF/spring,并添加org.springframework.boot.autoconfigure.AutoConfiguration.imports文件:

文件内容就是我们的的配置类:

然后就可以直接将该依赖给其它项目使用。 

如果需要像springboot官方的starter一样,导入一个starter之后在yml中写一些配置就能直接改变bean的属性值(yml中的配置其实就是一个个的bean对象,你改变配置其实就是在改bean的属性值),需要使用@ConfigurationProperties将bean和和配置文件绑定起来,再在configuration类上添加

@EnableConfigurationProperties注解。就能做到改yml配置文件就能修改bean的属性值,例如:

其实spring.factories文件这种做法其实在springboot3之后官方已经不再推荐使用,而是推荐使用

org.springframework.boot.autoconfigure.AutoConfiguration.imports

文件这种方式。

为什么不推荐使用spring.factories了

把作者的话翻译过来就是:

使用spring.factories查找自动配置类会给我们的本地工作带来问题。我们最初使用它是因为代码已经可用,但我们希望在2.7中提供一个替代方案,并在3.0中停止使用spring.factories进行自动配置。

这句话中的navite是关键,它并不是本地的意思。而是cloud native中的native。一切为了云原生!

springboot3中一个很大的特色就是增加了很多对云原生的支持!

我们知道,云原生时代中,最重要的是什么?启动速度。那Java如何提升启动速度?AOT编译+云原生镜像。可是,传统方法使用spring.factories依赖于运行时扫描和加载自动配置类,这么做效率肯定不高。不适合云原生!

相比之下,使用org.springframework.boot.autoconfigure.AutoConfiguration.imports这种方式,允许在编译时确定自动配置类,减少了运行时开销,并使得像GraalVM这样的工具更容易分析和编译Spring Boot应用到原生映像。这种方法可以带来更快的启动时间和更低的内存消耗,这对于从可扩展性和效率受益的云原生应用至关重要。

SpringBoot自动配置原理

每个spring-boot-starter-xxx能包含spring-boot-sarter,而spring-boot-starter中又包含spring-boot-autoconfigure。spring-boot-configure中包含了所有所有场景的配置类,es的、redis的、jdbc的......等等等:

每个自动配置类大概都长这样:

并且该模块中同样有org.springframework.boot.autoconfigure.AutoConfiguration.imports文件:

在该文件中把所有的xxxAutoConfiguration全都写进来了:

也就是说,只要这个包下的所有类都能生效,那么相当于SpringBoot官方写好的整合功能就生效了。但是SpringBoot默认却扫描不到 spring-boot-autoconfigure下写好的所有配置类默认只扫描主程序所在的包

然后就看主程序的@SpringBootApplication注解了:

这个注解由三个注解组成@SpringBootConfiguration@EnableAutoConfiguratio@ComponentScan。@SpringBootConfiguration和@Configuration功能差不多,都是将类定义为配置类,@ComponentScan注解默认扫主程序所在的包的。关键就是@EnableAutoConfiguratio:

 并且这个类中又使用了@Import导入了AutoConfigurationImportSelector类,这个类就是自动导入org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中的配置类:

(在springboot3之前是spring.factories:)

 至此,springboot就能把非主程序包的配置类全加载进来了。但是其实并不是全部都加载进来,而是按需加载!原因就在于每个配置类上都加了@ConditionOnxxx之类的注解,只有在这个条件成立的时候才会加载,例如:

拿@ConditionOnClass(JakartaWebServlet.class)举例,只有JakartaWebServlet存在时也就是这个依赖被导入时才加载。也就实现了你导入哪个依赖就加载哪个配置类,而不是全部都加载进来!

标签:怎么,SpringBoot,spring,配置,boot,autoconfigure,stater,bean,factories
From: https://blog.csdn.net/m0_73520938/article/details/143377715

相关文章

  • 【附源码+论文+ppt+部署教程】基于SpringBoot的网上订餐系统
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,源码已上传。点击文末名片获取个性化定制服务  摘 要随着我国经济的飞速发展,人们的生活速度明显加快,在餐厅吃饭排队的情况到处可见,近年来由于新兴IT行业的空前发展,它与传统餐饮行业也进行了新旧的结合,......
  • SpringBoot 快速实现 api 加密!so easy~
    SpringBoot快速实现api加密!soeasy~项目介绍什么是RSA加密举个栗子第一个场景第二个场景加密实战实战准备新建一个springboot项目引入maven依来启动类Application中添加@EnableSecurity注解在application.yml或者application.properties中添加RSA公钥及私钥对Control......
  • Go:select时,如果通道已经关闭会怎么样?
    1.for循环里被关闭的通道packagemainimport( "fmt" "time")funcmain(){ c:=make(chanint) gofunc(){ time.Sleep(time.Second) c<-10 close(c) }() for{ select{ casex,ok:=<-c: fmt.Println(x,ok) time.Slee......
  • SpringBoot:Failed to obtain JDBC Connection解决方案
    在第一次给自己的SpringBoot链接mysql的时候会出现很多问题可能的问题和解决方案本地的mysql没办法用root登陆这个一般是因为mysql在初始的时候默认root角色不能用密码登陆的原因可以用sudomysql先用最高权限进入mysql然后查看一下root的信息SELECTUser,Host,pl......
  • 如何用3个月零基础入门网络安全?_网络安全零基础怎么学习
    ......
  • SpringBoot抗疫物资管理:技术与策略
    第五章系统功能实现5.1管理员登录管理员登录,通过填写用户名、密码、角色等信息,输入完成后选择登录即可进入抗疫物资管理系统,如图5-1所示。5.2管理员功能实现图5-1管理员登录界面图5.2.1用户管理管理员对用户管理获取用户名、用户姓名、头像、性别、年龄、手机号码......
  • 抗疫物资管理:SpringBoot技术革新
    第六章系统测试软件测试它是对做完一个系统进行最后的一项工作,因为我们在做系统的时候,在进行编码以后可以开始对软件进行测试,在测试当中我们可以找出这个软件的错误与缺陷,这样我们可以及时处理,不影响后期正常的使用,同时也方便我们在后期使用过程中出现的问题容易去找出。......
  • 基于SpringBoot的在线考试系统
    引言  在信息化教育的浪潮中,在线考试系统成为了提高考试效率和优化资源配置的重要工具。传统的纸质考试流程不仅需要大量人力物力,还存在着批阅时间长、成绩分析困难等问题,难以满足快速发展的教育需求。本文介绍了一个基于SpringBoot+Vue+MySQL+MyBatis实现的在线......
  • 【SpringBoot】Jedis和Lettuce的区别
    Springboot整合Lettucespringboot2.0版本后,spring-boot-starter-data-redis提供了Lettuce代替Jedis。<!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId......
  • GitLab上怎么创建项目(步骤详解)
    创建项目在GitLab上需经过几个主要步骤:1.注册并登录账户;2.创建新项目;3.初始化及配置项目;4.代码管理与协作;5.持续集成/持续部署(CI/CD)的设置。首步为确保用户拥有一个GitLab账户并成功登录,紧接着便能通过简明的步骤创建并初始化自己的新项目,进而利用GitLab的多样功能进行代码管理和......