面试官:好久不见,很想念。今天就来说说SpringBoot的自动配置吧?考生:嗯,我觉得SpringBoot的自动配置是SpringBoot的一个很重要的“特性”。众所周知,SpringBoot有“约定大于配置”的概念,这在一定程度上可以用“SpringBoot自动配置”来解释。考生:SpringBoot自动配置的原理比较简单易懂。我们在使用SpringBoot的时候,肯定会依赖autoconfigure这样的包。考生:autoconfigure包中会有一个spring.factories文件,里面为每个入口定义了100+个配置类。比如我们常用的redis、kafka等常见的中间件,都预置了配置类候选项:当我们启动SpringBoot项目时,内部会加载spring.factories文件,然后“需要”加载配置班级。那么在我们使用相关组件的时候就会非常方便(因为配置类已经初始化了很大一部分配置信息)。考生:一般我们只要在应用配置文件中写好相应的配置,就可以直接通过各种模板类来操作相应的组件。面试官:会加载所有的配置类吗?你怎么理解这个“需要”的配置类呢?考生:并不是所有的配置类都会被加载。如果我们不导入redis-starter包,那么Redis的配置类就不会被加载。具体来说,Spring是通过@ConditionalXXX来判断何时执行的。比如Redis的配置类会有@ConditionalOnClass({RedisOperations.class})配置,表示如果当前环境中有RedisOperations.class的字节码,则加载Redis的配置类。面试官:哦,原来如此。那么,你知道吗,Redis的配置类其实有初始化RedisTemplate对象的操作,那么假设我们没有引入redis-starter包,它是如何通过编译的呢?(当然其他配置类也可能有同样的情况)考生:嗯,我看源码的时候也发现了这个。其实相关的依赖是在autoconfigure包中定义的,只是标记为可选,只在编译环境下有效。然后可以编译它,但是它的依赖项不会传递到我们的应用程序项目中。考生:这块还是花了我不少时间,最后在GitHub的SpringBoot源码中找到了。采访者:嗯,有一点。说到这里,那么谈谈你对SpringBootstarter的理解呢?考生:嗯,启动器是为了方便调用者使用相关组件。Spring框架还为我们实现了许多有用的启动器。考生:比如我们之前使用Mybatis框架,可能会引入各种包来使用。starter是一层封装,把所有要用到的jar包起来,也写了对应的version。我们在使用的时候不需要再引入一堆jar包和管理版本之类的问题。考生:现在很多开源组件都提供了对应的springboot-starter包供我们使用。制作入门包并不难。参考Spring内置实现即可:1.在项目中引入启动器打包相关的依赖。2.在我们的项目中构建spring.factories文件,写上我们配置类的全类名。面试官:嗯,我大概都明白了,是的。最后,大家怎么看这段源码呢?考生:源码的细节我可能不记得了,但是我还是有想法的。我先从启动类开始,会有@SpringBootApplication,然后定位到一个自动配置的注解@EnableAutoConfiguration,最后可以看到注解会去META-INF/spring.factories加载配置类应聘者:这个源码不难。在这个过程中,我也了解到maven有option和scope两个标签,但确实是SpringBoot比较重要的一个概念。面试官:好了,今天就到这里。题外话:这个关于自动配置的问题,确实问过几次了。说实话,关于Spring的类和注解的信息我是真的想不起来了。感觉能答出这个过程的idea,就够了(如果面试官真的想研究某个班名,那这种公司无所谓)。约定大于配置:SpringBoot为我们构建了很多配置类。这些配置类也初始化了很多配置(默认值)。当我们要使用它的时候,只需要覆盖这些配置项就可以了。即使我们不写,大多数情况下我们也不需要显式配置,但是可以正常访问相关组件。项目推荐如果你想学习Java项目,我还是强烈推荐我的开源项目新闻推送平台Austin,毕业设计和校招都可以使用。可以看到生产环境是如何推送消息的。Gitee仓库地址:https://gitee.com/zhongfuchen...GitHub仓库地址:https://github.com/ZhongFuChe...
