不懂Spring Boot自动装配还敢出去面试?

67 阅读5分钟

点击 程序员小胖 关注公众号 每日技术干货,第一时间送达!

最近跟一个朋友聊天, 他说了前几天出去找工作比较郁闷, 面试的时候问题回答的挺好的, 自己感觉也不错, 但是最后面试官还是说让回去等通知, 等了几天没结果主动问面试结果的时候, 果不其然, 面试没通过。

这时候我大概就知道了, 肯定是某一个基础问题回答的模棱两可, 被面试官认为技术水平一般, 所以就没通过。为什么我这么笃定, 因为我做面试官的时候就这样, 面试之前了解了候选人的工作经历和期望薪资之后对候选人在技术水平上会有一定的期待, 如果有几个低于预期的问题回答的模棱两可, 基本上我就会主动停止技术交流, 礼节性的问一些其他的问题, 然后结束本次面试, 结果嘛, 可想而知。

经过一翻交流,得知Spring Boot的自动装配回答的不行, 其实Spring boot自动装配是Spring中比较重要的一个核心知识点, 也是很容易学习的源码之一, 六年工作经验, 这个问题没回答出来, 面试没通过正常的。接下来我们简单的聊一下Spring Boot的自动装配。

自动配置流程图

源码的话就从@SpringBootApplication开始

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot 需要运行这个类的main方法来启动SpringBoot应用;

注解说明

@Target: 用来修饰注解的作用范围

@Retention:用于定义注解类被保留的时间长短,

@Documented:是标明当前的注解会被javac工具记录

@Inherited:是被这个注解标注是可以被继承的

@SpringBootConfiguration:Spring Boot的配置类,标注在某个类上, 表示这是一个Spring Boot的配置类;

@Configuration:配置类上来标注这个注解; 配置类配置文件; 配置类也是容器中的一个组件 Component

@EnableAutoConfiguration: 开启自动配置功能,以前我们需要配置的东西,Spring Boot帮我们自动配置;

@EnableAutoConfiguration:告诉SpringBoot开启自动配置, 会帮我们自动去加载自动配置类

@ComponentScan: 扫描包相当于在spring.xml配置中context:comonent-scan但是并没有指定basepackage, 如果没有指定spring底层会自动扫描当前配置类所有在的包

  • TypeExcludeFilter springboot对外提供的扩展类, 可以供我们去按照我们的方式进行排除
  • AutoConfigurationExcludeFilter 排除所有配置类并且是自动配置类中里面的其中一个

@EnableAutoConfiguration: 这个注解里面, 最主要的就是@EnableAutoConfiguration, 这么直白的名字,一看就知道它要开启自动配置,点进去@EnableAutoConfiguration的源码。

@AutoConfigurationPackage: 将当前配置类所在包保存在BasePackages的Bean中.其实就是注册了一个保存当前配置类所在包的一个Bean。

@Import(EnableAutoConfigurationImportSelector.class): 关键的地方到了, 在@EnableAutoConfiguration注解内使用到了@import注解来完成导入配置的功能, 而EnableAutoConfigurationImportSelector 实现了DeferredImportSelectorSpring内部在解析@Import注解时会调用getAutoConfigurationEntry方法. 下面是实现源码: getAutoConfigurationEntry方法进行扫描具有META-INF/spring.factories文件的jar包

任何一个springboot应用, 都会引入spring-boot-autoconfigure, 而spring.factories文件就在该包下面. spring.factories文件是 Key=Value形式, 多个Value时使用,隔开,该文件中定义了关于初始化, 监听器等信息, 而真正使自动配置生效的key是 org.springframework.boot.autoconfigure.EnableAutoConfiguration, 如下所示: 等同于 @Import({

})

每一个这样的xxxAutoConfiguration类都是容器中的一个组件, 都加入到容器中; 用他们来做自动配置; 所有自动配置类表每一个自动配置类进行自动配置功能; 后续: @EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在 SpringApplication.run(...)的内部就会执行selectImports()方法, 找到所有JavaConfig自动配置类的全限定名对应的class, 然后将所有自动配置类加载到Spring容器中.

以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;

@Configuration(proxyBeanMethods = false): 标记了@Configuration Spring底层会给配置创建cglib动态代理。作用就是防止每次调用本类的Bean方法而重新创建对象,Bean是默认单例的

@EnableConfigurationProperties(ServerProperties.class): 启用可以在配置类设置的属性对应的类 @xxxConditional根据当前不同的条件判断, 决定这个配置类是否生效?

@Conditional派生注解(Spring注解版原生的@Conditional作用)作用 必须是@Conditional指定的条件成立, 才给容器中添加组件, 配置配里面的所有内容才生效;

@Conditional扩展注解作用判断是否满足当前指定条件
@ConditionalOnJava系统的java版本是否符合要求
@ConditionalOnBean容器中存在指定Bean
@ConditionalOnMissingBean容器中不存在指定Bean
@ConditionalOnExpression满足SpEL表达式指定
@ConditionalOnClass系统中有指定的类
@ConditionalOnMissingClass系统中没有指定的类
@ConditionalOnSingleCandidate容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty系统中指定的属性是否有指定的值
@ConditionalOnResource类路径下是否存在指定资源文件
@ConditionalOnWebApplication当前是web环境
@ConditionalOnNotWebApplication当前不是web环境
@ConditionalOnJndiJNDI存在指定项

如果想要知道哪些自动配置类生效了; 我们可以通过设置配置文件中debug=true属性来让控制台打印自动配置报告, 这样我们就可以很方便的知道哪些自动配置类生效了。

Spring boot的自动装配原理明白了没,没明白的话就对着源码多看几遍吧,其实真的没有那么难的