面试官:好久没见,甚是惦记。明天来聊聊 SpringBoot 的主动配置吧?
候选者:嗯,SpringBoot 的主动配置我感觉是 SpringBoot 很重要的“个性”了。家喻户晓,SpringBoot 有着“约定大于配置”的理念,这一理念肯定水平上能够用“SpringBoot 主动配置”来解释。
候选者:SpringBoot 主动配置的原理了解起来挺简略的,咱们在应用 SpringBoot 的时候,必定会依赖于 autoconfigure 这么一个包
候选者:autoconfigure 这个包里会有一个 spring.factories 文件,该文件定义了 100+ 个入口的配置类。比方咱们常常应用的 redis、kafka 等等这样常见的中间件都 预置 了配置类
候选者:当咱们在启动 SpringBoot 我的项目的时候,外部就会加载这个 spring.factories 文件,进而去加载“有须要”的配置类。那咱们在应用相干组件的时候,就会十分的不便(因为配置类曾经初始化了一大部分配置信息)。
候选者:个别咱们只有在 application 配置文件写上对应的配置,就能通过各种 template 类间接操作对应的组件啦。
面试官:那是所有的配置类都会加载吗?这个“有须要”的配置类你是怎么了解的?
候选者:不是所有的配置类都会加载的,假如咱们没有引入 redis-starter 的包,那 Redis 的配置类就不会被加载。具体 Spring 在实现的时候就是应用 @ConditionalXXX进行判断的。比方 Redis 的配置类就会有 @ConditionalOnClass({RedisOperations.class})的配置,阐明以后环境下如果有 RedisOperations.class 这个字节码,才会去加载 Redis 的配置类
面试官:哦,这样啊,那理解了。那你知不知道 Redis 的配置类其实会有初始化 RedisTemplate 对象的操作,那假如咱们没有引入 redis-starter 包,那他是怎么通过编译的?(当然了,其余的配置类也是有可能有一样的情况)
候选者:嗯,这个我看源码的时候我也发现了。其实就是在 autoconfigure 包里 会定义到相干的依赖 ,但只是标记为 optional 并且只在编译环境无效。那这样是能通过编译的, 只是不会将其依赖传入到咱们的利用工程里。
候选者:这块还是花了我很多工夫的,我最初在 GitHub 的 SpringBoot 源码里找到的。
面试官:嗯啊,有点货色的哟。既然都聊到这块了,要不顺便聊聊你对 SpringBoot starter 的了解?
候选者:嗯,starter 这货色就是为了 不便调用方去应用相干的组件 的嘛,Spring 框架也给咱们实现了很多好用的 starter。
候选者:比方以前咱们要用 Mybatis 框架,可能会引入各种的包能力应用。而 starter 就是做了一层封装,把相干要用到的 jar 都给包起来了,并且也写好了对应的版本。这咱们应用的时候就不须要引入一堆 jar 包且治理版本相似的问题了。
候选者:当初很多开源的组件都会提供对应的 springboot-starter 包给咱们去用,要做一个 starter 包并不难。参照 Spring 内置的实现就好了:1、在工程里引入 starter 打包相干的依赖。2、在咱们工程内建 spring.factories 文件,编写咱们配置类的全限类名。
面试官:嗯,大抵都理解了,能够的。最初聊下你是怎么看这块源码的?
候选者:源码具体大略就不记得了,思路倒是还有的。我先从启动类开始,会有个 @SpringBootApplication,前面会定位到一个主动配置的注解 @EnableAutoConfiguration,那最初就能看到注解外部会去 META-INF/spring.factories 加载配置类
候选者:这块源码并不难,这个过程也理解到了原来 maven 有 option 和 scope 这俩标签,但的确是 SpringBoot 比拟重要的概念吧。
面试官:好嘞,明天到这就完结了吧。
题外:主动配置这个问题的确被问到过几次。说切实的,对于 Spring 类、注解的信息我真的记不住。感觉能答出这个流程思路,也就够用了(如果面试官的确是要细究某个类名,那这种公司不去也罢)
约定大于配置 :SpringBoot 给咱们内置了很多配置类,这些配置类也初始化了很多配置( 默认值)。当咱们要应用的时候,只须要笼罩这些配置项就完事了。即使咱们不写,大多数状况下都不须要由咱们显示配置进去,但相干组件就能失常拜访了。
举荐我的项目
如果想学 Java 我的项目的,我还是 强烈推荐 我的开源我的项目音讯推送平台 Austin,能够用作 毕业设计 ,能够用作 校招 ,能够看看 生产环境是怎么推送音讯 的。
Gitee 仓库地址:https://gitee.com/zhongfuchen…
GitHub 仓库地址:https://github.com/ZhongFuChe…