SpringBootSpringBoot自动装配原理解析

Posted Cry丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBootSpringBoot自动装配原理解析相关的知识,希望对你有一定的参考价值。

Springboot自动装配bean的过程

SpringBoot自动装配过程图

通过@Import(DeffredImportSelector)这个注解把所有Springboot帮我们把Spring需要集成的第三方框架中所默认配置的bean初始化成BeanDefination:如Mybatis中的SqlSessionFactory,SpringMvc中的InternalResourceViewResolver都是这样被自动装载进来的。我们可以通过@Import(类)或者@Import(ImportSelector)或者@Import(ImportBeanDefinition)3种方式导入,要一次扫描所有jar包中的Spring.factories并返回一个List,只有@Import(ImportSelector)这种方式可以做到,但是这种方式导入的Spring的bean可能会覆盖掉自己自定义的bean。所以SpringBoot通过实现一个DeferredImportSelector的接口来实现想要的目的,通过@Import(DeferredImportSelector)实现延迟加载和分组的功能,导入例如带有@ConditionalOnMissingBean(SqlSessionFactory.class)的bean来实现优先实现自定义的bean的效果,以及通过重写DeferredImportSelector接口的getImportGroup()方法来实现组内的bean排序加载(如果getImportGroup()返回的是Group.class,例如返回:


那么SpringBoot在加载默认bean的时候就会调用MyGroup的process()方法从而调到MyGroup的selectImports()方法返回一个分组排序后的beanList。

如果getImportGroup()返回的是null

那就直接调用DeferredImportSelector的selectImports()方法,直接返回一个存放class名的String数组,然后通过反射来实例化bean

Spring自动装配的源码

SpringBoot自动装配源码流程图





最终SpringBoot会找到jar包ClassLoader资源文件目录下的META-INF/spring.factories文件,读取里面的配置的bean生成类路径,如以下这个类就是一个生成bean的配置类:

我们可以看到SpringBoot会读取META-INF/spring.factories文件中key包含EnableAutoConfigurationn内容的value路径

SpringBoot首先会拿到127个自动配置类,它内部配置的所有的会根据pom中引入的依赖要决定在它的META-INF/spring.factories中配置的哪些是需要生效的,具体是通过OnBeanCondition.class、OnClassCondition.class、OnWebApplicationCondition.class来控制的.

  • OnClassCondition类在这三个类中优先级最高(@ConditionalOnClass、@ConditionalOnMissingClass),如果jar包中有加了这些注解的类则生效,如果没有则不生效
  • OnWebApplicationCondition用来检测容器的类型是否符合条件(@ConditionalOnWebApplication、ConditionalOnNotWebApplication),其优先级低于OnClassCondition类
  • OnBeanCondition类用来检测bean是否存在(@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnSingleCandidate)

通过在application.properties文件中配置debug=true,可以看到哪些自动配置类生效了

比如:AopAutoConfiguration,就可以看到它配置了@ConditionalOnProperty注解,默认全局配置文件中没有指定spring.aop.auto=true的时候也会生效

我们可以看到SpringBoot2.0默认使用的Cglib动态代理:

我们可以通过配置spring.aop.proxy-target-class=false来手动指定使用JDK动态代理。

@Condition注解

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

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

自定义一个starter

github: https://github.com/chenruoyu0319/demo-spring-boot-starter

以上是关于SpringBootSpringBoot自动装配原理解析的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot简要笔记

SpringBootSpringBoot 自动配置原理

SpringBootSpringBoot配置文件及YAML简介

SpringBootSpringBoot 配置这一篇文章就够了

SpringBootSpringBoot 配置这一篇文章就够了

SpringBootSpringBoot web开发