本文只对自动配置的思想进行基本的解读,不涉及源码层面的深入解读。
要点1:什么是自动配置?
pring Boot根据我们的开发行为自动猜测并准备使用的bean,只要开发者导入相关的类,Spring Boot就能自动加载可能需要用到的bean,无需开发者手动配置,从而简化了开发流程。
自动配置的意义就是加速开发效率,将开发者使用某种技术时需要使用的bean根据情况提前加载好,实现自动配置的效果。当然,开发者有可能需要提供必要的参数,比如你要用mysql技术,导入了mysql的坐标,springboot就知道了你要做数据库操作,一系列的数据库操作相关的bean都给你提前声明好,但是你要告诉springboot你到底用哪一个数据库,像什么IP地址啊,端口啊,你不告诉spirngboot,springboot就无法帮你把自动配置相关的工作做完。
要点2:配置文件与默认配置
要点1具体:如何实现如果我在配置文件中配置了就使用配置文件里的内容,如果没有则加载默认的。简单的来看是以下demo代码演示的
整体demo模拟效果为如果我在配置文件中配置了cat的名字跟年龄则用配置文件内的,否则默认的名字为jerry,年龄为18.
先通过yml配置文件,设置bean运行需要使用的配置信息。
cat: name: tom age: 16
然后定义一个封装属性的专用类,加载配置属性,读取对应前缀相关的属性值。
@Data @ConfigurationProperties(prefix = "cat") public class CatAutoProperties { private String name; private Integer age; }
注意写到这里的时候会报错,因为 @ConfigurationProperties只能加载由spring容器管理的bean,在这里我并没有添加@Component注解交给容器管理。
定义我们要使用bean如下:
@Data @EnableConfigurationProperties(CatAutoProperties.class) public class Cat { private String name; private Integer age; public Cat(CatAutoProperties catAutoProperties) { if (catAutoProperties!=null&&catAutoProperties.getAge()!=null){ age=catAutoProperties.getAge(); }else { age=88; } if (catAutoProperties!=null&&catAutoProperties.getName()!=null){ name=catAutoProperties.getName(); }else { name="jerry"; } } }
@EnableConfigurationProperties(CatAutoProperties.class)这个意思是将CatAutoProperties加载为bean。@ConfigurationProperties读取配置文件只能是bean自动读取 (解决前面的报错误)
测试主程序为:
@SpringBootApplication @Import(Cat.class) public class SsmpApplication { public static void main(String[] args) { ConfigurableApplicationContext applicationContext = SpringApplication.run(SsmpApplication.class, args); Cat bean = applicationContext.getBean(Cat.class); System.out.println(bean); } }
修改配置文件为如下:
cat: name: tom # age: 16
再次运行结果如下:
综上所述该demo已模拟出自动配置的要点1。
总结:
- bean的运行如果需要外部设置值,建议将设置值封装成专用的属性类* * * * Properties
- 设置属性类加载指定前缀的配置信息
- 在需要使用属性类的位置通过注解@EnableConfigurationProperties加载bean,而不要直接在属性配置类上定义bean,减少资源加载的数量,因需加载而不要饱和式加载。
要点3:自动配置设置思想来源
阶段一:准备阶段
- springboot的开发人员先大量收集Spring开发者的编程习惯,整理开发过程每一个程序经常使用的技术列表,形成一个技术集A
- 收集常用技术(技术集A)的使用参数,不管你用什么常用设置,我用什么常用设置,统统收集起来整理一下,得到开发过程中每一个技术的常用设置,形成每一个技术对应的设置集B
阶段二:加载阶段
- springboot初始化Spring容器基础环境,读取用户的配置信息,加载用户自定义的bean和导入的其他坐标,形成初始化环境
- springboot将技术集A包含的所有技术在SpringBoot启动时默认全部加载,这时肯定加载的东西有一些是无效的,没有用的
- springboot会对技术集A中每一个技术约定出启动这个技术对应的条件,并设置成按条件加载,由于开发者导入了一些bean和其他坐标,也就是与初始化环境,这个时候就可以根据这个初始化环境与springboot的技术集A进行比对了,哪个匹配上加载哪个
- 因为有些技术不做配置就无法工作,所以springboot开始对设置集B下手了。它统计出各个国家各个行业的开发者使用某个技术时最常用的设置是什么,然后把这些设置作为默认值直接设置好,并告诉开发者当前设置我已经给你搞了一套,你要用可以直接用,这样可以减少开发者配置参数的工作量
- 但是默认配置不一定能解决问题,于是springboot开放修改设置集B的接口,可以由开发者根据需要决定是否覆盖默认配置
要点4:spring.factories文件作用
spring.factories文件是Spring Boot自动配置的核心文件之一,它的作用是将各种自动配置类与对应的配置类集中在一起,方便Spring Boot自动装配。在Spring Boot启动时,它会扫描classpath下所有的spring.factories文件,加载其中的自动配置类,并将它们注入到Spring ApplicationContext中,使得项目能够自动运行。该文件的格式为键值对,键是自动配置类的全限定名,值是该自动配置类所对应的配置类的全限定名。
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.itheima.bean.CartoonCatAndMouse
这个文件就做了一件事,通过这种配置的方式加载了指定的类。转了一圈,就是个普通的bean的加载,和最初使用xml格式加载bean几乎没有区别
要点5:自动配置的核心
- 自动配置从根本上来说就是一个bean的加载
- 通过bean加载条件的控制给开发者一种感觉,自动配置是自适应的,可以根据情况自己判定,但实际上就是最普通的分支语句的应用
- 使用bean的时候,如果不设置属性,就有默认值,如果不想用默认值,就可以自己设置,也就是可以修改部分或者全部参数,感觉这个过程好屌,也是一种自适应的形式,其实还是需要使用分支语句来做判断的
- springboot技术提前将大量开发者有可能使用的技术提前做好了,条件也写好了,用的时候你导入了一个坐标,对应技术就可以使用了,其实就是提前帮我们把spring.factories文件写好了
总结:
- springboot启动时先加载spring.factories文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration配置项,将其中配置的所有的类都加载成bean
- 在加载bean的时候,bean对应的类定义上都设置有加载条件,因此有可能加载成功,也可能条件检测失败不加载bean
- 对于可以正常加载成bean的类,通常会通过@EnableConfigurationProperties注解初始化对应的配置属性类并加载对应的配置
- 配置属性类上通常会通过@ConfigurationProperties加载指定前缀的配置,当然这些配置通常都有默认值。如果没有默认值,就强制你必须配置后使用了