SpringBoot自动配置原理流程图
SpringBoot的优势之一是简化了配置,其自动配置原理也是面试高频题之一
下面我们来分析下SpringBoot的自动配置原理
启动类
启动类:
-
package com.
qzcsbj.
demo;
-
-
import org.
springframework.
boot.
SpringApplication;
-
import org.
springframework.
boot.
autoconfigure.
SpringBootApplication;
-
-
@SpringBootApplication
-
public
class
ApidemoApplication {
-
-
public
static
void
main(
String[] args) {
-
SpringApplication.
run(
ApidemoApplication.
class, args);
-
}
-
}
@SpringBootApplication表示这个类是启动类
@SpringBootApplication是一个复合注解
下面把@SpringBootApplication替换为@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan,程序一样可以正常启动并访问
-
package com.
qzcsbj.
demo;
-
-
import org.
springframework.
boot.
SpringApplication;
-
import org.
springframework.
boot.
SpringBootConfiguration;
-
import org.
springframework.
boot.
autoconfigure.
EnableAutoConfiguration;
-
import org.
springframework.
boot.
autoconfigure.
SpringBootApplication;
-
import org.
springframework.
context.
annotation.
ComponentScan;
-
-
// @SpringBootApplication
-
@SpringBootConfiguration
-
@EnableAutoConfiguration
-
@ComponentScan
-
public
class
ApidemoApplication {
-
-
public
static
void
main(
String[] args) {
-
SpringApplication.
run(
ApidemoApplication.
class, args);
-
}
-
}
so,@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
@SpringBootConfiguration
@Component组件,说明启动类本身也是Spring中的一个组件
@ComponentScan
-
<?xml version
=
"1.0" encoding
=
"UTF-8"?
>
-
<beans xmlns
=
"http://www.springframework.org/schema/beans"
-
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:context
=
"http://www.springframework.org/schema/context"
-
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
>
-
-
<!--扫描包--
>
-
<context:component-scan base-package
=
"com.qzcsbj.*"
/
>
-
-
<
/beans
>
演示
创建maven项目,添加spring依赖然后创建实体类
-
package com.qzcsbj.bean;
-
-
import lombok.AllArgsConstructor;
-
import lombok.Data;
-
import lombok.NoArgsConstructor;
-
import org.springframework.beans.factory.
annotation.Value;
-
import org.springframework.stereotype.Component;
-
-
/**
-
* @description : <描述>
-
*/
-
@Data
-
@NoArgsConstructor
-
@AllArgsConstructor
-
@Component
-
public
class
Person {
-
@Value("123")
-
private int id;
-
-
@Value("jack")
-
private String name;
-
}
在config下创建TestConfig配置类,指定扫描路径
-
package com.qzcsbj.config;
-
-
import org.springframework.context.
annotation.ComponentScan;
-
import org.springframework.context.
annotation.Configuration;
-
-
/**
-
* @description : <描述>
-
*/
-
@Configuration
-
@ComponentScan("com.qzcsbj")
// 指定扫描路径
-
public
class
TestConfig {
-
}
除了自己,还扫描到person了(springboot中不需要指定,默认是扫描父包)
测试:TestConfig就相当于以前的xml文件
-
package com.qzcsbj;
-
-
import com.qzcsbj.bean.Person;
-
import com.qzcsbj.config.TestConfig;
-
import org.junit.
Test;
-
import org.junit.runner.RunWith;
-
import org.springframework.beans.
factory.annotation.Autowired;
-
import org.springframework.
test.context.ContextConfiguration;
-
import org.springframework.
test.context.junit
4.SpringJUnit
4ClassRunner;
-
-
/
**
-
* @description : <描述>
-
*/
-
@RunWith(SpringJUnit
4ClassRunner.
class)
-
@ContextConfiguration(classes
= TestConfig.
class)
-
public
class MyTest {
-
@Autowired
-
Person person;
-
-
@
Test
-
public void
test(){
-
System.out.println(
"person: "
+ person);
-
}
-
}
@EnableAutoConfiguration
@EnableAutoConfiguration :开启自动配置功能
@Import(AutoConfigurationImportSelector.class)给容器导入组件(选择器)
其中,重点是@Import(AutoConfigurationImportSelector.class),点击AutoConfigurationImportSelector
点击继承的接口ImportSelector(选择器)
关注下面这个方法
返回到AutoConfigurationImportSelector类,定位到selectImports方法(类中实现了这个方法)
点击getAutoConfigurationEntry方法
该方法中的getCandidateConfigurations方法,返回一个自动配置类的类名列表
configurations这个list存的是所有自动化配置类的全类名,都是AutoConfiguration结尾的,这些是框架已经写好的自动配置类
点击getCandidateConfigurations方法
SpringFactoriesLoader是工具类,点击loadFactoryNames方法
点击loadSpringFactories方法
springboot
![](https://img-blog.csdnimg.cn/img_convert/d8abf5f9e9137664211cb8fa6c4189f6.png)
自动配置生效
-
@ConditionalOnBean:当容器里有指定的bean的条件下
-
@ConditionalOnMissingBean:当容器里不存在指定bean的条件下
-
@ConditionalOnClass:当类路径下有指定类的条件下
-
@ConditionalOnMissingClass:当类路径下不存在指定类的条件下
比如mybatis
要生效,我们需要导入对应的场景启动器
-
<dependency
>
-
<groupId
>org.mybatis.spring.boot
<
/groupId
>
-
<artifactId
>mybatis-spring-boot-starter
<
/artifactId
>
-
<version
>
2.0.0
<
/version
>
-
<
/dependency
>
点击mybatis-spring-boot-starter
可以看到有如下依赖,导入了下面的依赖,上面条件判断,SqlSessionFactory和SqlSessionFactoryBean就肯定存在了
![](https://img-blog.csdnimg.cn/img_convert/7860c123c6587a85770761ed6077b43b.png)
总结
核心原理:Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。