【面试题】SpringBoot自动配置原理

SpringBoot自动配置原理流程图

SpringBoot的优势之一是简化了配置,其自动配置原理也是面试高频题之一

下面我们来分析下SpringBoot的自动配置原理

启动类

启动类:


     
     
  1. package com. qzcsbj. demo;
  2. import org. springframework. boot. SpringApplication;
  3. import org. springframework. boot. autoconfigure. SpringBootApplication;
  4. @SpringBootApplication
  5. public class ApidemoApplication {
  6. public static void main( String[] args) {
  7. SpringApplication. run( ApidemoApplication. class, args);
  8. }
  9. }

@SpringBootApplication表示这个类是启动类

@SpringBootApplication是一个复合注解 

下面把@SpringBootApplication替换为@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan,程序一样可以正常启动并访问


     
     
  1. package com. qzcsbj. demo;
  2. import org. springframework. boot. SpringApplication;
  3. import org. springframework. boot. SpringBootConfiguration;
  4. import org. springframework. boot. autoconfigure. EnableAutoConfiguration;
  5. import org. springframework. boot. autoconfigure. SpringBootApplication;
  6. import org. springframework. context. annotation. ComponentScan;
  7. // @SpringBootApplication
  8. @SpringBootConfiguration
  9. @EnableAutoConfiguration
  10. @ComponentScan
  11. public class ApidemoApplication {
  12. public static void main( String[] args) {
  13. SpringApplication. run( ApidemoApplication. class, args);
  14. }
  15. }

so,@SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan

@SpringBootConfiguration

标注在某个类上,表示这是一个SpringBoot的配置类
@SpringBootConfiguration = @Configuration

@Component组件,说明启动类本身也是Spring中的一个组件

@ComponentScan

自动扫描并加载符合条件的组件或者bean,加载到IOC容器中
老写法 

     
     
  1. <?xml version = "1.0" encoding = "UTF-8"? >
  2. <beans xmlns = "http://www.springframework.org/schema/beans"
  3. xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context = "http://www.springframework.org/schema/context"
  5. 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" >
  6. <!--扫描包-- >
  7. <context:component-scan base-package = "com.qzcsbj.*" / >
  8. < /beans >

演示

创建maven项目,添加spring依赖然后创建实体类


      
      
  1. package com.qzcsbj.bean;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import org.springframework.beans.factory. annotation.Value;
  6. import org.springframework.stereotype.Component;
  7. /**
  8. * @description : <描述>
  9. */
  10. @Data
  11. @NoArgsConstructor
  12. @AllArgsConstructor
  13. @Component
  14. public class Person {
  15. @Value("123")
  16. private int id;
  17. @Value("jack")
  18. private String name;
  19. }

在config下创建TestConfig配置类,指定扫描路径


      
      
  1. package com.qzcsbj.config;
  2. import org.springframework.context. annotation.ComponentScan;
  3. import org.springframework.context. annotation.Configuration;
  4. /**
  5. * @description : <描述>
  6. */
  7. @Configuration
  8. @ComponentScan("com.qzcsbj") // 指定扫描路径
  9. public class TestConfig {
  10. }

除了自己,还扫描到person了(springboot中不需要指定,默认是扫描父包)

测试:TestConfig就相当于以前的xml文件


      
      
  1. package com.qzcsbj;
  2. import com.qzcsbj.bean.Person;
  3. import com.qzcsbj.config.TestConfig;
  4. import org.junit. Test;
  5. import org.junit.runner.RunWith;
  6. import org.springframework.beans. factory.annotation.Autowired;
  7. import org.springframework. test.context.ContextConfiguration;
  8. import org.springframework. test.context.junit 4.SpringJUnit 4ClassRunner;
  9. / **
  10. * @description : <描述>
  11. */
  12. @RunWith(SpringJUnit 4ClassRunner. class)
  13. @ContextConfiguration(classes = TestConfig. class)
  14. public class MyTest {
  15. @Autowired
  16. Person person;
  17. @ Test
  18. public void test(){
  19. System.out.println( "person: " + person);
  20. }
  21. }

@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

自动配置生效

每一个自动配置类都是在某些条件之下才会生效


     
     
  1. @ConditionalOnBean:当容器里有指定的bean的条件下
  2. @ConditionalOnMissingBean:当容器里不存在指定bean的条件下
  3. @ConditionalOnClass:当类路径下有指定类的条件下
  4. @ConditionalOnMissingClass:当类路径下不存在指定类的条件下

比如mybatis

要生效,我们需要导入对应的场景启动器


     
     
  1. <dependency >
  2. <groupId >org.mybatis.spring.boot < /groupId >
  3. <artifactId >mybatis-spring-boot-starter < /artifactId >
  4. <version > 2.0.0 < /version >
  5. < /dependency >

点击mybatis-spring-boot-starter

可以看到有如下依赖,导入了下面的依赖,上面条件判断,SqlSessionFactory和SqlSessionFactoryBean就肯定存在了

总结

核心原理:Spring Boot启动的时候会通过@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定,然后再通过@EnableConfigurationProperties注解导入到Spring容器中。

【back】

原文已更新:https://www.cnblogs.com/uncleyong/p/17067567.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值