1、依赖管理
1)父项目(继承依赖,声明了各种jar包依赖版本号)
几乎声明了所有开发中常用的依赖的版本号
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
</parent>
2)自定义依赖版本号(pom.xml)
1、查看spring-boot-dependencies里面规定当前依赖的版本。
2、在当前项目里面重写配置
<properties>
<mysql.version>8.0.26</mysql.version>
</properties>
3)Starters场景启动器
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: 第三方为我们提供的简化开发的场景启动器。
所有场景启动器最底层的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.2</version>
<scope>compile</scope>
</dependency>
2、自动配置
自动配好Tomcat(依赖/配置)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.7.2</version>
<scope>compile</scope>
</dependency>
自动配好SpringMVC(引入MVC全套组件/自动配好其常用组件)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
<scope>compile</scope>
</dependency>
自动配好Web常见功能,如字符编码问题(所有web开发的常见场景)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.22</version>
<scope>compile</scope>
</dependency>
默认包结构
主程序同级的包及子包里面的所有组件都默认扫描到,可用@SpringBootApplication(scanBasePackages=“com.yzh”)改变扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.yzh.boot")
各种配置都有默认值(默认配置最终都是映射到MuitipartProperties)
按需加载所有自动配置项(根据场景Starter引入)
3、容器功能
1)组件添加
@Configuration
Full模式与Lite模式
package com.yzh.boot.config;
import com.yzh.boot.bean.Pet;
import com.yzh.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true) 【保证每个@Bean方法返回的组件都是单实例的】
* Lite(proxyBeanMethods = false)【每个@Bean方法返回的组件都是新创建的】
* 组件依赖必须使用Full模式。
*/
@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
@Bean //给容器中添加组件。以方法名作为组件的id 返回类型就是组件类型 返回的值,就是组件在容器中的实例
public User user01(){
User user = new User("叶子航", 20,tomcatPet());
//User组件依赖了Pet组件
user.setPet(tomcatPet());
return user;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
@Import
@Import(xxx.class,xxx.class):给容器中自动创建出这两个类型的组件
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}
@Conditional
条件装配(满足指定装配,则进行组件注入)
package com.yzh.boot.config;
import ch.qos.logback.classic.db.DBHelper;
import com.yzh.boot.bean.Pet;
import com.yzh.boot.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2、配置类本身也是组件
* 3、proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true) 【保证每个@Bean方法返回的组件都是单实例的】
* Lite(proxyBeanMethods = false)【每个@Bean方法返回的组件都是新创建的】
* 组件依赖必须使用Full模式。
*/
@Import({User.class}) //给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
//@ConditionalOnBean(name = "tom") 若容器中没有这个组件,则下面所有组件都不生效
public class MyConfig {
@Bean(name="tom")
public Pet pet(){
return new Pet("tomcat");
}
@Bean //给容器中添加组件。以方法名作为组件的id 返回类型就是组件类型 返回的值,就是组件在容器中的实例
@ConditionalOnBean(name = "tom")
public User user01(){
User user = new User("叶子航", 20,pet());
return user;
}
}
2)原生配置文件引入
@ImportResource
将xml创建的bean加入容器
<bean id="user" class="com.yzh.boot.bean.User"></bean>
@ImportResource("classpath:beans.xml")
3)配置绑定
@Component + @ConfigurationProperties
将配置文件配置的属性值配置到创建的bean并加入到容器
package com.yzh.boot.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix ="mycar" )
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {
private String brand;
private Integer price;
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
mycar.brand="宝马"
mycar.price=100
@EnableConfigurationProperties + @ConfigurationProperties
将指定的bean注入容器
4、自动配置原理
@SpringBootApplication
@SpringBootConfiguration
@Configuration(表明是个配置类)
@EnableAutoConfiguration
@AutoConfigurationPackage(自动配置包)
@Import({Registrar.class}) (批量注册,Registrar.class见下图)
@Import({AutoConfigurationImportSelector.class}) (配置全加载但按需分配 见下图)
@ComponentScan(包扫描,指定扫描)
1)引导加载自动配置类
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
//获取主程序的包名并其包下的所有组件注册到容器
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0]));
}
2)按需开启自动配置项
@Import({AutoConfigurationImportSelector.class})
虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。
3)修改默认配置
SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先
SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration,每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值
xxxProperties和配置文件进行了绑定,生效的配置类就会给容器中装配很多组件,只要容器中有这些组件,相当于这些功能就有了
定制化配置-----用户直接自己@Bean替换底层的组件,用户去看这个组件是获取的配置文件什么值就去修改
xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 ----> application.properties