谈谈你对自动装配的原理的理解

谈谈你对自动装配的原理的理解

首先,我们使用传统的spring开发的话需要导入很多jar包,比如在这里插入图片描述
而SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,比如spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件,我们只需加一个依赖就可以省这么多事。

引入一个starter所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器(starter)即可,Starter 组件会把对应功能的所有 jar 包依赖全部导入进来,避免了开发者自己去
引入依赖带来的麻烦
。当然,我们也可以自己自定义 starter。

springboot-boot-starter-xxx:就是spring-boot的场景启动器。

那么starter还干了啥了呢,还有啥作用呢?

Starter 内部集成了自动装配的机制,也就说在程序中依赖对应的 starter 组件以后,这个组件自动会集成到 Spring 生态下,并且对于相关 Bean 的管理,也是基于自动装配机制来完成。

例如我想要在SpringBoot项目中集成Redis,那么我只需要加入spring-data-redis-starter的依赖,并简单配置一下连接信息以及Jedis连接池配置就可以,我们没有写redis的装配过程直接加一个依赖就解决了,这就是自动装配

总结自动装配,简单来说就是自动把第三方组件的 Bean 装载到 Spring IOC 器里面,不需要开发人员再去写 Bean 的装配配置。

引入 Starter 启动依赖组件的时候,这个组件里面必须要包含@Configuration 配置类,在这个配置类里面通过@Bean 注解声明需要装配到 IOC 容器的 Bean 对象。所以我们在自定义starter的时候就这样写。这个配置类是放在第三方的 jar 包里面的,然后通过 SpringBoot 中的约定优于配置思想,把这个配置类的全路径放在 classpath:/META-INF/spring.factories 文件中。这样 SpringBoot 就可以知道第三方 jar 包里面的配置类的位置,这个步骤主要是用到了 Spring 里面的 SpringFactoriesLoader 来完成的。

提一下约定优于配置大概啥意思,我也搞了好久。我认为就是springboot帮我们搞定了那些繁琐的配置,我们不需要再手动配置啦,都约定好了,springboot的这些约定省去了我们自己配,所以就是约定优于配置。

所以自动配置是咋实现的呢?

在 Spring Boot 应用里面,只需要在启动类加上@SpringBootApplication 注解就可以实现自动装配。

  • @SpringBootApplication 是 一 个 复 合 注 解
    在这里插入图片描述

  • @ComponentScan
    作用:扫描主配置类包的所有包下的类,相当于xml配置文件中的context:component-scan。eg:pojo中的User类

  • @EnableAutoConfiguration
    真 正 实 现 自 动 装 配 的 注 解 是@EnableAutoConfiguration(@AutoConfigurationPackage+@Import)。而EnableAutoConfiguration也是一个复合注解,它包含@AutoConfigurationPackage+@Import。
    在这里插入图片描述

  • 下面就来谈谈@AutoConfigurationPackage注解。
    在这里插入图片描述

    作用:给Spring容器中导入一个Registrar注册器组件。

@AutoConfigurationPackage和@ComponentScan一样,也是将主配置类所在的包及其子包里面的组件扫描到IOC容器中,但是区别是@AutoConfigurationPackage扫描@Enitity、@MapperScan等第三方依赖的注解。这就解释了为什么要把自己的组件写到与主启动类同包下。
@ComponentScan只扫描@Controller/@Service/@Component/@Repository这些常见注解。所以这两个注解扫描的对象是不一样的。

  • @Import(AutoConfigurationImportSelector.class)——核心注解
    作用:通过import导入第三方提供的bean的配置类:AutoConfigurationImportSelector:即 @Import(AutoConfigurationImportSelector.class),给容器导入组件。

    该类中有selectImports()方法,调用了getAutoConfigurationEntry()
    在这里插入图片描述
    其下又调用了getCandidateConfigurations()
    在这里插入图片描述
    getCandidateConfigurations()中SpringFactoriesLoader.loadFactoryNames()方法扫描jar包类路径下的META-INF/spring.factories文件下,获取BeanConfiguration列表
    在这里插入图片描述
    loadFactoryNames方法会读取spring.factories中EnableAutoConfiguration.class类名对应的值
    在这里插入图片描述
    最终扫描所有jar包类路径下的META-INF/spring.factories文件,加载自动配置类

那么这么多配置类每次都要加载吗?不是

我们在spring.factories文件中找一个类看看
在这里插入图片描述

@Configuration(proxyBeanMethods = false)————表示该类为配置类
@EnableConfigurationProperties(ServerProperties.class)————将配置文件中设置的值与properties中的属性绑定,将组件添加到IOC容器
————@Conditionalxxx:若满足不同的条件,则配置类中的配置生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = “server.servlet.encoding”, value = “enabled”, matchIfMissing = true)

其中ServerProperties.class中的属性值,可与xx.yaml配置文件绑定并修改。

总结:根据当前配置类的条件判断配置类是否生效,若生效,则添加各种组件,会从properties类中获取属性,可以在配置文件xxx.yaml中设置属性的值

  • Properties类:封装配置文件的相关属性。
  • AutoConfiguration类:自动配置类,添加到IOC容器中。

SpringFactoriesLoader

  • 作用:从classpath/META-INF/spring.factories文件中,根据key来加载对应的类到spring IOC容器中。

自动装配过程

  • 通过各种注解实现了类与类之间的依赖关系,容器在启动的时候SpringApplication.run(),调用EnableAutoConfigurationImportSelector.class的selectImports方法
  • selectImports方法调用SpringFactoriesLoader.loadFactoryNames方法扫描jar包类路径下的META-INF/spring.factories文件下,获取BeanConfiguration列表
  • loadFactoryNames方法会读取spring.factories中EnableAutoConfiguration.class类名对应的值
    根据这些类上的注解判断,若条件满足,则该配置类生效,将配置文件中自己设置的属性值配置到对应的配置类中,最后注入到IOC容器中实现自动配置

总结

SpringBoot通过@EnableAutoConfiguration注解找到META-INF/spring.factories文件中的所有自动配置类,并对其加载,这些自动配置类都是以AutoConfiguration结尾来命名的。它实际上就是一个JavaConfig形式的IOC容器配置类,通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如server.port,最后通过@Conditional按需加载配置类。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值