SpringBoot特点
依赖管理
#依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
#自定义修改版本号
<properties>
<mysql.version>x.x.xx</mysql.version>
</properties>
#dependencies中不再需要添加版本号
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
#不在版本仲裁中的jar包需要写上版本号。
starter场景启动器
基于spring-boot-starter-*,通过引入各种场景,会自动引入当前场景所需的开发依赖。
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot.html#using-boot-starter
*-spring-boot-starter :第三方提供。
自动配置
- Tomcat的引入和配置
- SpringMVC相关组件的配置
- Web开发场景配置
- 默认包结构配置(无需包扫描配置)
- 各种配置的默认值(映射到某个类上)[可以在application.properties配置文件中设定值]
- 按需加载自动配置项(源自spring-boot-autoconfigure包)
- ……
@SpringBootApplication(scanBasePackages="com.xxx.xxx")
等价于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.xxx.xxx")
容器功能
组件添加
- @Configuration
- @Bean、@Component、@Controller、@Service、@Repository
- @ComponentScan、@Import
- @Conditional
Configuration
Configuration作为配置类标注,即为Spring简要入门中的Java装配。
1. 配置类里面用@Bean标注在方法上给容器注册组件,默认单实例
2. 配置类本身也是组件
3. proxyBeanMethods ---> 代理Bean的方法
Full(proxyBeanMethods = true) 每一次调用都返回代理对象
Lite(proxyBeanMethods = false) 每一次调用都产生新对象
配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
配置类组件之间有依赖关系,方法会被调用得到之前创建的单实例组件,用Full模式
Import
/**
* 给容器自动创建出导入类型的组件,默认组件名就是全类名
*/
@Import({A.class, B.class})
@Configuration
public class AppConfig{
}
Conditional
条件装配,满足条件后进行注入。示例如下
public class AppConfig{
/**
* 容器中有名为A的组件时,才会注入B
*/
@ConditionalOnBean(name = "A")
@Bean
public B b(){
return new B("b");
}
}
ImportResource
针对需要用到xml装配的java装配模式,使用@ImportResource,相当于将xml配置文件的内容引入。
@ImportResource("classpath:beans.xml")
public class AppConfig{
}
配置绑定
用来帮助Java读取properties配置文件中的数据。
application.properties
pref.str = str_of_prefix
pref.itr = 0
Component + ConfigurationProperties
/**
* 加入容器中才生效。prefix为前缀,即为properties中的名称。
*/
@Component
@ConfigurationProperties(prefix = "pref")
public class A{
private String str;
private Integer itr;
}
EnableConfigurationProperties + ConfigurationProperties
/**
* 在引用第三方类时,无法在第三方类中标注@Component,可以使用这种方式。
*/
@ConfigurationProperties(prefix = "pref")
public class A{
private String str;
private Integer itr;
}
/**
* 在AppConfig(配置类)中标注@EnableConfigurationProperties
*/
@EnableConfigurationProperties(A.class)
//开启类A的配置绑定功能
//把A组件自动注册到容器中
public class AppConfig{
}
自动配置原理入门
引导加载自动配置类
- SpringBootConfiguration
- Configuration:代表当前是一个配置类
- ComponentScan
- 指定扫描哪些,Spring注解;
- EnableAutoConfiguration
- AutoConfigurationPackage:将指定的一个包下的所有组件导入进来
- Import(AutoConfigurationPackages.Registrar.class)
- 类Registrar:利用Import导入的Registrar中的函数批量注册组件
- 方法registerBeanDefinitions(metadata, registry)
- metadata:注解的源信息
- new PackageImports(metadata).getPackageNames():获取源信息的包名
- 方法register:把包下的所有组件批量注册
- 方法registerBeanDefinitions(metadata, registry)
- 类Registrar:利用Import导入的Registrar中的函数批量注册组件
- Import(AutoConfigurationPackages.Registrar.class)
- Import(AutoConfigurationImportSelector.class)
- 方法selectImports:获取需要导入进容器的配置名称组
- 方法getAutoConfigurationEntry:得到所有需要注入的配置的集合
- 方法getCandidateConfigurations:获取所有候选(默认导入)的配置
- 方法SpringFactoriesLoader.loadFactoryNames
- 方法loadSpringFactories:得到所有的组件
- 从META-INF/spring.factories位置来加载文件
- 默认扫描当前系统里所有META-INF/spring.factories位置的文件
- 在spring-boot-autoconfigure-x.x.x.RELEASE.jar包中META-INF/spring.factories中记录了给容器中加载的所有配置类
- 方法loadSpringFactories:得到所有的组件
- 方法SpringFactoriesLoader.loadFactoryNames
- 方法getCandidateConfigurations:获取所有候选(默认导入)的配置
- 方法getAutoConfigurationEntry:得到所有需要注入的配置的集合
- 方法selectImports:获取需要导入进容器的配置名称组
- AutoConfigurationPackage:将指定的一个包下的所有组件导入进来
按需开启自动配置项
自动配置启动时虽然默认全部加载,但最终会按需配置。
得益于条件装配机制(@Conditional),很多机制并不会开启。
修改默认配置
给容器中加入了文件上传解析器
@Bean
@ConditionalOnBean(MultipartResolver.class)
//容器中有这个类型组件
@ConditionalOnMissingBean(name=DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
//容器中没有这个名字为multipartResolver的组件
public MultipartResolver multipartResolver(MultipartResolver resolver){
//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
return resolver;
}
SpringBoot默认会在底层配好所有组件。若用户自己配置了,以用户配置的组件优先。
- SpringBoot先加载所有的自动配置类,*AutoConfiguration
- 每个自动配置类按照条件进行生效,默认绑定配置文件指定的值(可直接修改properties文件修改)
- 如果生效,生效的配置类会给容器中装配相关组件
- 只要容器中存在这些组件,就可以实现相关功能
- 定制化配置
- 用户直接创建新Bean替换底层组件
- 用户找到相关properties文件,直接修改
对2的注解:自动配置中,方法里传入的参数是从容器中拿的,容器中的值通过EnableConfigurationProperties绑定,从properties文件导入进来。
*AutoConfiguration —> 组件 —> *Properties中取值 —> application.properties