springboot 自动装配

Posted mcjmcl

tags:

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

springboot最大特点就是自动装配

一.什么是自动配置?

根据特定条件自动将一些配置类的bean注册进ioc容器,使得可以在需要的地方直接从容器中获取和使用
? “自动”的表现形式就是我们只需要引我们想用功能的jar包,相关的配置我们完全不用管(springboot内置了很多的**start配置信息)

二.如何实现自动配置?

主要是依赖**@EnableAutoConfiguration+@Conditional**来实现的

1.spring boot启动run方法的时候,要有一个@SpringBootApplication注解的资源类(属于@Configuration),prepareContext方法时加载进容器

2.SpringBootApplication注解类上有一个@EnableAutoConfiguration

3.EnableAutoConfiguration注解类上有一个@Import(AutoConfigurationImportSelector.class)

4.spring创建上下文,会注册ConfigurationClassPostProcessor.class的BeanDefinition类定义(实现BeanDefinitionRegistryPostProcessor接口)到容器中

5.spring容器在刷新refresh的时候会调用invokeBeanFactoryPostProcessors(beanFactory)方法,实例化ConfigurationClassPostProcessor对象

6.有了ConfigurationClassPostProcessor对象,继续执行BeanDefinitionRegistryPostProcessor##postProcessBeanDefinitionRegistry的方法

7.BeanDefinitionRegistryPostProcessor##postProcessBeanDefinitionRegistry方法中,实例化ConfigurationClassParser对象并执行parser方法,操作容器中所有带注解的类(@SpringBootApplication),并找到@Import注解后面跟的value值,如果value值类型是DeferredImportSelector接口类型,放到集合中,循环执行getCandidateConfigurations方法

8.在AutoConfigurationImportSelector##getCandidateConfigurations(AnnotationMetadata metadata,AnnotationAttributes attributes)方法,里面有一行:List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());注意loadFactoryNames方法的这两个参数!扫描所有jar包类路径下/META-INF/spring.factories文件中的EnableAutoConfiguration,能得到很多配置类(包括自定义的和org.springframework.boot.autoconfigure项目的所有)

9.在上面得到的很多List<String> configurations的,删除重复的、excluded的、过滤OnClassConditional、OnBeanConditional、OnWebApplicationConditional匹配不上的

10.然后触发AutoConfigurationImportEvent事件,告诉ConditionEvaluationReport条件评估报告器对象来分别记录符合条件和exclude的自动配置类,最后spring再将筛选成功后的类导入IOC容器中

11.org.springframework.boot.autoconfigure项目内置了很多的自动配置,所以如果需要使用这些配置,直接引用对应的jar包(或者引用对应的start jar包,效果一样的),其实spring-boot-starter-XXX这个项目也就是引入一下XXX需要的包而已,什么都没做,所以自动引用和使用start引用,没有什么区别

三.例子

在springboot之前,我们要在自己的spring应用中使用redis,要引入redis.clients、spring-data-redis两个引用,并在项目中自己设置配置
有了springboot后,只需要引入spring-boot-starter-redis一个引用,不用自己设置配置;或者引入redis.clients、spring-data-redis两个引用,不用自己设置配置

 技术图片

四.看一个真实的自动装配org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration(autoconfigure项目中,引入了很多的jar包依赖,但都是编译时依赖,打成的autoconfigure.jar包中,不会有对应的class类存在!)

技术图片

解释上面几个注解:
1、@Configuration标注这个类是一个配置类
2、@ConditionalOnClass(RedisOperations.class):判断当前classpath下是否存在RedisOperations.class,若存在则将当前的配置类装载入spring容器
3、@ConditionalOnMissingBean(name = "redisTemplate"):判断当前spring容器中是否存在name为redisTemplate的对象,若不存在则将当前的对象装载入spring容器

org.springframework.boot.autoconfigure.data.redis.RedisProperties 提供了一些默认的配置信息

技术图片

五.自定义start

自定义一个****start项目,写自己的***configuration和****properties,META-INF/spring.factories,key:org.springframework.boot.autoconfigure.EnableAutoConfiguration value值指向自己的***configuration,项目中引入自定义的start包即可

技术图片

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

spring boot自动装配原理

SpringBoot学习探究Springboot自动装配

springboot自动装配---实现一个自定义自动装配组件

SpringBoot自动装配

springboot自动装配

SpringBoot自动装配流程