文章目录
5.1 引导加载自动配置类
-
Spring Boot应用的启动类:
@SpringBootApplication public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }
或者
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { ... }
5.1.1 @SpringBootConfiguration
- @SpringBootConfiguration:代表当前类是一个配置类
5.2.2 @ComponentScan
- @ComponentScan:指定扫描的路径
5.2.3 @EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
-
@AutoConfigurationPackage
:自动配置包,指定了默认的包规则。利用Registrar给容器中导入一系列组件。@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import(AutoConfigurationPackages.Registrar.class)// 利用Registrar给容器中导入一系列组件 public @interface AutoConfigurationPackage { String[] basePackages() default {}; Class<?>[] basePackageClasses() default {}; }
-
@Import(AutoConfigurationImportSelector.class):默认扫描我们当前系统里面所有
META-INF/spring.factories
位置的文件,获取到所有需要导入到容器中的配置类xxxxAutoConfiguration
。(似乎新版本的Spring Boot把所有类的META-INF/spring.factories合起来放在一起了,一共一百多个)。
5.2 按需开启自动配置项
-
虽然一共加载了一百多个
xxxxAutoConfiguration
配置类,但实际上,这些配置类中都包含了条件装配注解(@Conditional
),按照条件装配规则,最终会按需配置
。-
比如
AopAutoConfiguration
类:@Configuration(proxyBeanMethods = false) @ConditionalOnProperty( prefix = "spring.aop", name = {"auto"}, havingValue = "true", matchIfMissing = true ) public class AopAutoConfiguration { public AopAutoConfiguration() { } ... }
-
5.3 修改默认配置
-
以
DispatcherServletAutoConfiguration
的内部类DispatcherServletConfiguration
为例子:@Bean @ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件 @ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件 public MultipartResolver multipartResolver(MultipartResolver resolver) { return resolver;//给容器中加入了文件上传解析器; }
-
给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。目的是防止有些用户配置的文件上传解析器不符合规范。
-
SpringBoot默认会在底层配好所有的组件,但是
如果用户自己配置了以用户的优先
。
5.4 总结
- SpringBoot先加载所有的自动配置类xxxxAutoConfiguration
- 每个自动配置类按照条件进行生效
- 每个自动配置类都会从xxxxProperties类里面读取配置,xxxProperties和配置文件application.properties进行了绑定。
- 生效的配置类就会给容器中装配很多组件,只要容器中有这些组件,相当于这些功能就有了
- 如果程序员需要定制化配置,则可以:
- 直接自己在配置类中@Bean替换底层的组件
- 修改application.properties对于某个自动配置类的相关配置
xxxxxAutoConfiguration
----> xxxxProperties
----> application.properties
5.5 最佳实践-SpringBoot应用如何编写
引入场景依赖
查看自动配置了的详细信息
- 可以在配置文件中debug=true开启自动配置报告。
- Negative(不生效)
- Positive(生效)
- 可以在配置文件中debug=true开启自动配置报告。
是否需要修改配置
- 参照文档修改配置项,官方文档
- 自定义组件替换底层组件
- @Bean、@Component…
- 自定义器 XXXXXCustomizer;
- …
5.6 常用开发技巧
5.6.1 Lombok简化开发
-
基本使用:
Lombok用标签方式代替构造器、getter/setter、toString()等鸡肋代码
。 -
spring boot已经管理Lombok,并未集成了Lombok插件。只需要引入依赖即可使用:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-
示例
@Data @ToString @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode @Component public class User { private String name; private int age; private Pet pet; public User(String name, int age) { this.name = name; this.age = age; } }
-
各个注解的作用:
- @Data:自动生成get、set方法
- @ToString:自动生成toString方法
- @NoArgsConstructor:自动生成无参构造器
- @AllArgsConstructor:自动生成包含所有成员变量的有参构造器
- @EqualsAndHashCode:自动生成equal和hashcode方法
-
简化日志开发:使用@Slf4j注解
5.6.2 dev-tools
-
基本使用:可以使用ctrl+F9来重新启动项目
-
添加依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
-
我的评价是:鸡肋!
5.6.3 Spring Initailizr
- 基本使用:Spring Initailizr是创建Spring Boot工程向导
- IDEA中,在创建项目时,菜单栏New -> Project -> Spring Initailizr,勾选需要的开发场景,Spring Initailizr会自动构建好项目。