【面试题】SpringBoot自动配置原理
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.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 :开启自动配置功能
@Import(AutoConfigurationImportSelector.class)给容器导入组件(选择器)
其中,重点是@Import(AutoConfigurationImportSelector.class),点击AutoConfigurationImportSelector
点击继承的接口ImportSelector(选择器)
关注下面这个方法
返回到AutoConfigurationImportSelector类,定位到selectImports方法(类中实现了这个方法)
点击getAutoConfigurationEntry方法
该方法中的getCandidateConfigurations方法,返回一个自动配置类的类名列表
configurations这个list存的是所有自动化配置类的全类名,都是AutoConfiguration结尾的,这些是框架已经写好的自动配置类
点击getCandidateConfigurations方法
SpringFactoriesLoader是工具类,点击loadFactoryNames方法
点击loadSpringFactories方法
springboot
自动配置生效
@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容器中。
原文已更新:https://www.cnblogs.com/uncleyong/p/17067567.html
__EOF__
关于博主:擅长性能、全链路、自动化、企业级自动化持续集成(DevTestOps)、测开等
面试必备:项目实战(性能、自动化)、简历笔试,https://www.cnblogs.com/uncleyong/p/15777706.html
测试提升:从测试小白到高级测试修炼之路,https://www.cnblogs.com/uncleyong/p/10530261.html
欢迎分享:如果您觉得文章对您有帮助,欢迎转载、分享,也可以点击文章右下角【推荐】一下!