在Spring和SpringMvc中,如果我们要使用外部的bean,那么就要手动写一个Java配置类,然后用@Bean的方式把他们注入到容器里。
但是在SpringBoot中,如果要使用一个Mybatis,我们只要一个Mybatis的starter就可以了,这就是自动配置。
首先明确一点:为什么第三方的代码上也加了@Component却无法和我们的Bean一起注入容器。这是因为SpringBoot默认的ComponentScan范围
是我们的启动类所在目录及其子目录,所以第三方包无法被扫描到。
1.@EnableAutoConfiguration
在使用springboot时,我们并没有在Java配置类里面注入外部的bean,也不能在外部类上加@Component,而且这些类也不在我们的项目范围内,所以它们是如何加入到我们的容器中呢?
@EnableAutoConfiguration能把第三方bean注入到springboot中
,借鉴了JDK的SPI机制。
2.Java的SPI
(19条消息) 浅谈SPI扩展机制_&一步的博客-优快云博客_spi扩展
SPI就是:服务使用者定义接口,服务提供者实现接口并描述实现信息,Java负责类加载工作
就比如Java的Driver就是一个SPI,Java让各个数据库厂商去根据这个接口实现驱动,然后我们Java用户导一个驱动的jar包就可以获得服务
服务提供者将接口的实现信息写在resources/META-INF/services
下,文件名为接口的全类名
,内容为实现类的全类名。
//接口定义
void print();
//服务获取过程
ServiceLoader<Interface1> load = ServiceLoader.load(Interface1.class);
for (Interface1 interface1:load){
interface1.print();
}
文件格式,内部是实现类的全类名
com.example.demo.ClassA
com.example.demo.ClassB
流程:
3.SpringBoot的SPI
-
首先明确SpringBoot已经有两种自动装入的方式了,一种依赖
Factories
文件(1.0开始),一种依赖Imports
文件(2.7开始) -
直接跳到
AutoConfigurationImportSelector
,这个类就是专门用来加载自动装入的bean的。protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //这一步就是老的关键的自动装入过程 List<String> configurations = new ArrayList<>( SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader(