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
标注在某个类上,表示这是一个SpringBoot的配置类
@SpringBootConfiguration = @Configuration
@Component组件,说明启动类本身也是Spring中的一个组件
@ComponentScan
自动扫描并加载符合条件的组件或者bean,加载到IOC容器中
老写法
<?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.junit4.SpringJUnit4ClassRunner;
/**
* @description : <描述>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class MyTest {
@Autowired
Person person;
@Test
public void test(){
System.out.println("person: " + person);
}
}
@EnableAutoConfiguration
@EnableAutoConfiguration :开启自动配置功能
@AutoConfigurationPackage :自动配置包
@Import(AutoConfigurationImportSelector.class)给容器导入组件(选择器)
其中,重点是@Import(AutoConfigurationImportSelector.class),点击AutoConfigurationImportSelector
点击实现接口DeferredImportSelector,另外下面还实现了BeanClassLoaderAware
点击继承的接口ImportSelector(选择器)
关注下面这个方法
返回到AutoConfigurationImportSelector类,定位到selectImports方法(类中实现了这个方法)
点击getAutoConfigurationEntry方法
该方法中的getCandidateConfigurations方法,返回一个自动配置类的类名列表
debug
configurations这个list存的是所有自动化配置类的全类名,都是AutoConfiguration结尾的,这些是框架已经写好的自动配置类
点击getCandidateConfigurations方法
SpringFactoriesLoader是工具类,点击loadFactoryNames方法
点击loadSpringFactories方法
类加载器,加载类路径是所有META-INF/spring.factories文件
springboot
mybatis
自动配置生效
每一个自动配置类都是在某些条件之下才会生效
@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就肯定存在了
总结
核心原理:Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。
【bak】
__EOF__
本文作者:持之以恒(韧)
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevOps/TestOps)、测开等