SpringBoot自动配置原理

SpringBoot开始

1.1、依赖管理

  • 父项目做依赖管理
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>

spring-boot-starter-parent的父项目是spring-boot-dependencies可以看看里面有哪些东西

spring-boot-dependencies几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制

  • 启动器

    1、见到很多 spring-boot-starter-* : *就某种场景
    2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
    3、SpringBoot所有支持的场景
    https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
    4、见到的 *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
    5、所有场景启动器最底层的依赖:

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    
  • 无需关注版本

    1、引入依赖默认都可以不写版本
    2、引入非版本仲裁的jar,要写版本号。

    3、修改默认版本号 :

    1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。
    2、在当前项目里面重写配置
        <properties>
            <mysql.version>5.1.43</mysql.version>
        </properties>
    

1.2、自动配置

以web项目为例

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

这个启动器配置了:

  • Tomcat

  • SpringMVC

  • Web常见功能,如:字符编码问题

  • 默认的包结构、

    • 主程序(主方法所在类)所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.atguigu”)
      • 或者@ComponentScan 指定扫描路径
  • @SpringBootApplication
    等同于
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan("com.chr.boot")
    public class MainApplication {
        public static void main(String[] args) {
          ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);  
        }
    }
    
  • 各种配置拥有默认值

    • 默认配置最终都是映射到某个类上,如:MultipartProperties
    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
  • 按需加载所有自动配置项

    • 非常多的starter
    • 引入了哪些场景这个场景的自动配置才会开启
    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

容器功能

2.1、组件添加

1、@Configuration配合@Bean

  • 基本使用
  • Full模式与Lite模式
    • 配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
    • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
/**
 * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
 * 2、配置类本身也是组件
 * 3、proxyBeanMethods:代理bean的方法
 *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
 *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
 *      组件依赖必须使用Full模式默认。其他默认是否Lite模式
 *
 *
 *
 */
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {

    /**
     * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
     * @return
     */
    @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Pet组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

2、@ComponenScan

在组件类上@Component、@Controller、@Service、@Repository

3、@Import

  • 位置放在配置类上
@Import({User.class, DBHelper.class})
给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}

@Import 高级用法: https://www.bilibili.com/video/BV1gW411W7wy?p=8

4、@Conditional

条件装配:满足Conditional指定的条件,则进行组件注入

  • 加在配置类上代表该配置类加载所有组件时都需要这个条件
  • 也可加在返回组件的方法上,只控制一个组件的
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
@ConditionalOnMissingBean(name = "tom")
public class MyConfig {
}

2.2、原生配置文件引入

1、@ImportResource

将beans.xml(spring配置文件)里面的组件通过@ImportResource("classpath:beans.xml")加载

2.3、配置绑定

application.properties配置文件存放某些组件需要的属性

1、@ConfigurationProperties

在给Car类的属性赋值时只需要在application.properties配置文件中配置mycar.brand=xxx;mycar.price=xxx即可

/**
 * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
 */
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {

    private String brand;
    private Integer price;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

2、@EnableConfigurationProperties + @ConfigurationProperties

  • 一般使用这种方式
@EnableConfigurationProperties(Car.class) // 开启 Car 的属性配置并自动注入到容器中
public class MyConfiguration {
}
@ConfigurationProperties(prefix = "car")
public class Car {}

3、@Component + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
public class MyConfig {
}

自动配置原理入门

官方starter一般为 spring-boot-starter-xxx

第三方starter一般为 xxx-spring-boot-starter

starter的自动配置过程

通过自定义starter来理解自动配置

  • xxx-starter工程(普通工程)引入xxx-starter-autoconfigure工程(是一个springboot工程)–>

  • 包含xxxAutoConfiguration类(会在工程启动时被读取),且该配置类通过@EnableConfigurationProperties(xxxproperties.class)注解

    @Configuration
    // 绑定配置文件的配置(组件所需要的属性可以配置在bean类中,bean类通过读取配置文件来获取值)
    @EnableConfigurationProperties(HelloServiceProperties.class)
    public class HelloServiceAutoConfiguration {
    	// 向容器加载组件
        @Bean
        @ConditionalOnMissingBean(HelloService.class)
        public HelloService helloService(){
            return new HelloService();
        }
    }
    
  • 绑定一个xxxproperties的bean类,改bean类又通过@ConfigurationProperties(String prefix)和配置文件的值进行绑定

    @ConfigurationProperties("hello")
    public class HelloServiceProperties {
        String prefix;
        String suffix;
       // getter、setter...
    }
    
  • 最后通过将xxx-starter-autoconfigure的配置类的全类名放在配置文件classpath:META-INF/spring.factories即src/main/resources/META_INF/spring.factories的``org.springframework.boot.autoconfigure.EnableAutoConfiguration=/`中。

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.chr.hello.auto.HelloServiceAutoConfiguration
    

这样配置类就会在项目启动时通过读取所有的spring.factories文件中的配置类将其加载在容器中,配置类中的各种组件也随之被加载到了容器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值