一、SpringBoot的特点
1)依赖管理
<!--父依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--父依赖的父依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.3</version>
</parent>
<!--在SpringBoot的项目中我们添加依赖几乎不需要我们自己写版本号
因为在它的父依赖中几乎声明了所有的版本号-->
<!--SpringBoot项目加载场景启动器-->
<!--所有的场景启动器最底层的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.3</version>
<scope>compile</scope>
</dependency>
- 无效设置版本号,自动闭包仲裁
引入jar默认都可以不设置版本号,自动仲裁
非仲裁jar包,需要自己设定版本号
- 修改默认仲裁的版本号
<!--首先 查看spring-boot-dependencies里面规定当前依赖的版本 用的 key-->
<!--设置更改-->
<properties>
<mysql.version>5.1.43</mysql.version>
</properties>
2)自动配置
- 在SpringBoot中不需要我们自己配置TomCat,它已经帮我们配置好了
- 自动配置SpringMVC
- 自动引入、配置SpringMVC组件(功能)
- 自动配置好web常见功能:字符编码问题等。
- SpringBoot帮我们配置好了几乎所有的web开发常见场景
- 默认包结构
- 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
- 无需以前的包扫描配置
- 想要改变扫描路径,使用注解 @SpringBootApplication(scanBasePackages=“com.xin”)
- 或者@ComponentScan 指定扫描路径
@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.xin.boot")
- 各种配置都拥有默认值
- 默认配置最终都是映射到某个类上绑定,这个类会在容器中创建对象
- 按需加载所有自动配置项
- 非常多的starter,引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
二、容器功能
1)组件
1、@Configuration
- Full模式与Lite模式
- Full模式,(proxyBeanMethods = true),【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
- Lite模式,Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
- 组件依赖必须使用Full模式默认。其他默认是否Lite模式
2、@Bean、@Component、@Controller、@Service、@Repository
/*
Configuration: 告诉SpringBoot,这是一个配置类
配置类本身就是一个组件
proxyBeanMethods: 代理Bean的方法,把我们创建代理对象(组件),默认值为 true
false: 每一个组件每一次调用时返回的组件都是新创建的,若是类中的各个组件有依赖关系就使用
true: 每一个组件每一次调用时返回的组件都是单实例的
*/
@Configuration(proxyBeanMethods = true) //Full模式
//加载配置文件到容器
@ImportResource("classpath:beans.xml")
public class MyConfig {
@Bean //给容器中添加组件。以方法名作为组件的id。
public User user() {
return new User("张三",18,tomCat());
}
@Bean
public Pet tomCat() {
return new Pet("tomcat",89.5);
}
}
3、@ComponentScan、@Import
@Import({User.class, DBHelper.class})
//给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
/*
@ComponentScan:
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
这两个属性用于指定包路径进行扫描
nameGenerator: 指定生成的bean的名称
basePackageClasses: 用于指定某一个类的包的路径进行扫描
useDefaultFilters: 是否对@Component、@Respository、@Service、@Controller的类进行检测,默认为true
ComponentScan.Filter[] includeFilters() default {}; 包含过滤条件
*/
//扫描com.xin.pojo包下的没有被注解的Car类
@ComponentScan(value = "com.xin.pojo" ,
includeFilters =
{@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Car.class})})
//扫描service包下的类
@ComponentScan(value = "com.xin.service" ,
useDefaultFilters = true)
4、@Conditional
条件装配:满足Conditional指定的条件,则进行组件注入
2)原生配置文件引入
@ImportResource
//加载配置文件到容器
@ImportResource("classpath:beans.xml")
//路径从根目录下开始
3)配置绑定
使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用
/**
* 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
*/
@Component
@ConfigurationProperties(prefix = "mycar") //取前缀为为mycar的属性值
public class Car {
...
}
//若是car实体类上没有使用@Component注解将car注册到容器中那么就要使用@EnableConfigurationProperties注册
//@EnableConfigurationPropertiesz需要注解在配置类上,不能在实体类上
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中
@EnableConfigurationProperties(Car.class)
public class MyConfig {
}
//使用了@ConfigurationProperties注解的实体类必须要在容器中注册,不然会报错
三、自动配置原理入门 – 注解的作用
1)@SpringBootApplication
注解在主程序类上,表示这是一个SpringBoot应用
在它的上面除了四个元注解,还有这三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class})})
public @interface SpringBootApplication {
}
2)@SpringBootConfiguration 与 @Configuration
- @SpringBootConfiguration 表示SpringBoot的注解类,查看源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
有源码可以看出@SpringBootConfiguration注解内有一个核心注解@Configuration
- @Configuration 注解是Spring框架提供的
被@Configuration 注解的类,代表是一个配置类,注解以后,就会初始化这个类下所有加了@Bean的方法,并初始化这个bean
由此可知,@SpringBootConfiguration 与 @Configuration的作用相同,都是将一个类标识为配置类,@SpringBootConfiguration 是被SpringBoot 框架进行了重新封装命名的而已
3)@ComponentScan
该注解用来指定哪些Spring注解,定义扫描的路径,默认就会加载标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中, excludeFilters 指定扫描的时候需要排除的组件,includeFilters 指定扫描的时候只包含的组件 ** @filter**过滤器注解
如果不设置value属性,默认扫描路径是启动类所在目录及其子目录
useDefaultFilters :是否对含有@Controller,@Service,@Repository,@Component注解的类开启检测,默认是开启的
@ComponentScan(value = "com.xin.pojo" ,
useDefaultFilters = true,
includeFilters =
{@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {Car.class})})
public class MyConfig {
}
4)@EnableAutoConfiguration
进入源码可知,它的内部有两个最主要的注解,@Import,@AutoConfigurationPackage
它的本质上还是一个 @Import注解
作用:帮助SpringBoot应用将所有符合条件的@Configuration
配置都加载到当前SpringBoot创建并使用的IoC容器。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
}
1. @AutoConfigurationPackage
由源码可知,@AutoConfigurationPackage 注解的核心是@Import 注解
作用:自动配置包,指定默认的包规则
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class}) 、、//利用Registrar给容器中导入一系列组件
public @interface AutoConfigurationPackage {}
2. @Import
@Import({AutoConfigurationImportSelector.class})
//给容器中批量导入组件
//获取所有需要导入容器中的配置类
//利用工厂加载,得到所有的组件
//默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
//spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
所以说SpringBoot项目在初始化时,会将我们所需要的大多数的组件已经提前帮我们导入容器了。
@SpringBootApplication
public class SpringBootStudyApplication {
public static void main(String[] args) {
//返回IOC容器
ConfigurableApplicationContext context = SpringApplication.run(SpringBootStudyApplication.class, args);
//查看容器中的组件的数量及名字
System.out.println("容器中有组件数:" + context.getBeanDefinitionCount()); //springboot内部会自己产生很多的组件
String[] names = context.getBeanDefinitionNames();
//遍历组件名
for (String name : names) {
System.out.println(name);
}
}
}
个人理解:@EnableAutoConfiguration,注解的底层是@Import注解,而@Import注解在SpringBoot项目中会帮我们把多数的组件都导入到容器中,在我们的主程序类中的@SpringBootApplication注解的内部又是@EnableAutoConfiguration注解,所以说SpringBoot项目启动时会帮我们加载了许多的组件到容器中,自动的帮我们配置好了绝大多数的东西。
5)@Conditional
条件装配注解,按照我们的需求开启SpringBoot帮我们配置的场景组件
虽然所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration,但是并不是把所有的配置都开启了的,会根据条件来按照我们的需求开启的。开启相应的配置场景,就可以使用相应的组件了,就相当于我们可以使用相应的功能了。
修改默认配置
SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
@Bean
//@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
// Detect if the user has created a MultipartResolver but named it incorrectly
//检测用户是否创建了MultipartResolver但命名不正确
return resolver;
}
//给容器中加入了文件上传解析器;
总结
- SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
默认配置类都在这个包中
- 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值
- 生效的配置类就会给容器中装配很多组件
- 默认的 xxxxxAutoConfiguration 配置类都会和相应的 xxxProperties 文件绑定,从其中去默认值。
- 只要容器中有这些组件,相当于这些功能就有了
四、小技巧
1)自动配置报告
导入相应的场景依赖项就可以开启相应的配置项,使用其功能。
在配置文件中设置 debug = true ,可以开启自动配置报告,查看开启了那些配置
2)Lombok插件
简化JavaBean开发。
- 安装Lombok插件
- 导入 Lombok 依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- @Data:
注解在类上;包含了@ToString,@EqualsAndHashCode,@Getter / @Setter和@RequiredArgsConstructor的功能,提供类所有属性的 getter 和 setter 方法,此外还提供了equals、canEqual、hashCode、toString 方法
- @ToString:
注解在类上;生成toString()方法
- @Slf4j
注解在类上;根据用户实际使用的日志框架生成log日志对象
- @Log4j
注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
- @EqualsAndHashCode
注解在类上;生成hashCode()和equals()方法
- @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法。
- @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
- @NonNull: 注解在属性上;标识属性是不能为空,为空则抛出异常。
- …