SpringBoot 笔记(一)
1.基础入门
1.1 依赖管理
- 父项目做依赖管理
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
</parent>
他的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.2</version>
</parent>
spring-boot-dependencies 几乎声明了所有开发中常用的依赖的版本号。
......
<ehcache.version>2.10.6</ehcache.version>
<ehcache3.version>3.9.0</ehcache3.version>
<elasticsearch.version>7.9.3</elasticsearch.version>
<embedded-mongo.version>2.2.0</embedded-mongo.version>
<flyway.version>7.1.1</flyway.version>
<freemarker.version>2.3.30</freemarker.version>
<git-commit-id-plugin.version>3.0.1</git-commit-id-plugin.version>
<glassfish-el.version>3.0.3</glassfish-el.version>
......
- starter场景启动器
Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors.
All official starters follow a similar naming pattern; spring-boot-starter-*, where * is a particular type of application.
As explained in the “Creating Your Own Starter” section, third party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts. Rather, a third-party starter typically starts with the name of the project. For example, a third-party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-starter.
- 无需关注版本号,自动仲裁
引入依赖默认都可以不写版本号。
引入非版本仲裁的jar,要写版本号。
1.2自动配置
- 自动配好Starter场景中常用的组件。
- 默认的包结构。
主程序所在的包及其子包都会被包扫描进来。
无需以前的包扫描配置
When a class does not include a package declaration, it is considered to be in the “default package”. The use of the “default package” is generally discouraged and should be avoided. It can cause particular problems for Spring Boot applications that use the @ComponentScan, @ConfigurationPropertiesScan, @EntityScan, or @SpringBootApplication annotations, since every class from every jar is read.
想要改变扫描路径:
@SpringBootApplication(scanBasePackages="com.keepromise")
或者
@ComponentScan("com.keepromise")
- 各种配置有默认值
可以通过application.properties文件修改默认值。
- 按需加载所有的自动配置项
引入了那些场景,这个场景的自动配置才会开启。
SpringBoot所有的自动配置功能都在spring-boot-autoconfig包里面。
2.容器功能
2.1组件添加
1.@Configuration
//@Configuration注解定义
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
/* 告诉springboot,这是一个配置类,配置类本身也是组件。
1.配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单例。
2.配置类本身也是组件。
3.proxyBeanMethods==true :myconfig底层是springboot生成的CGLIB代理对象;==false:myconfig不是代理对象。
Full(==true)
Lite(==false)
* */
@Configuration
public class Myconfig {
/**
* 外部无论对配置类中的这个组件注册方法调用多少次,获取到额都是之前注册在容器中的单实例对象。proxyBeanMethods=true
* */
@Bean //给容器添加组件。以方法名作为组件id,返回类型是组件类型。返回值,就是组件在容器中的实例。
public User user01(){//springboot底层通过运行该方法产生bean实例,而不是通过代理。
return new User("zhangsan",20);
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
2.@Bean,@component,@Controller,@Service,@Repository
3.@Import
//@Import注解定义
public @interface Import {
/**
* {@link Configuration @Configuration}, {@link ImportSelector},
* {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
*/
Class<?>[] value();
}
该注解需要加在一个springboot组件上,才会起作用。
4.@Conditional
条件装配,满足条件则进行组件装配,可以加在类上或者方法上。
The @Conditional annotation may be used in any of the following ways:
- as a type-level annotation on any class directly or indirectly annotated with @Component, including @Configuration classes
- as a meta-annotation, for the purpose of composing custom stereotype annotations
- as a method-level annotation on any @Bean method
@ConditionalOnBean(name="tom")//容器中有tom才装配下面的组件,包括Myconfig组件。
@Configuration
public class Myconfig {
@ConditionalOnBean(name="tom")//容器中有tom才装配user01组件。
@Bean //给容器添加组件。以方法名作为组件id,返回类型是组件类型。返回值,就是组件在容器中的实例。
public User user01(){//springboot底层通过运行该方法产生bean实例,而不是通过代理。
return new User("zhangsan",20);
}
//此时容器中没有tom组件。
// @Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
5.@ImportResource
导入xml配置文件中的组件。
2.2 配置绑定
如何读取properties文件中的内容,并把它封装到JavaBean中?
1.@ConfigurationProperties
//定义一个Bean
@Component
@ConfigurationProperties(prefix = "mycar") //绑定的类要有setter方法。
public class Car {
String brand;
int price;
public void setBrand(String brand) {
this.brand = brand;
}
public void setPrice(int price) {
this.price = price;
}
public String getBrand() {
return brand;
}
public int getPrice() {
return price;
}
}
//application.properties文件中添加
mycar.brand = BTD
mycar.price = 100000
//测试
Car car = run.getBean(Car.class);
System.out.println(car.getBrand()+car.getPrice());
//输出
BTD100000
2.@EnableConfigurationProperties
该注解指定那个类可以和配置文件进行绑定,和@ConfigurationProperties搭配使用。
3.自动配置入门
3.1引导加载自动配置类
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication{
......
}
1.@SpringBootConfiguration
和@Configuration一样
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
2.@ComponentScan
指定扫描哪些包。
3.@EnableAutoConfiguration
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
.....
}
1.@AutoConfigurationPackage
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
.....
}
//利用Registrar.class给容器中导入一系列组件
//AutoConfigurationPackage注解的作用是将 添加该注解的类所在的package 作为 自动配置package 进行管理。
2.@Import({AutoConfigurationImportSelector.class})
1.利用getAutoConfigurationEntry(annotationMetadata),给容器中导入一些组件
2。调用List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes),获取所有要导入到容器的配置类(组件)。
3.调用Map<String, List<String>> loadSpringFactories(ClassLoader classLoader),得到所有组件
Enumeration urls = classLoader.getResources("META-INF/spring.factories")
默认扫描META-INF/spring.factories位置的文件。
spring-boot-autoconfigure-2.4.2.jar包里面的META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
......
3.2按需开启自动配置项
虽然我们的130个场景的所有自动配置启动的时候默认全部加载。(即上述META-INF/spring.factories内容)
按照条件装配规则,最终会按需配置。即(@@Conditional),springboot源码会在自动配置类中加上一些条件注解,来使得按需配置。
总结:
- SpringBoot先加载所有的自动配置类。
- 每个自动配置类按条件生效,默认都会绑定配置文件指定的值。
- 生效的自动配置类就会给容器中装配很多组件。
- 只要容器中有这些组件,相当于这些功能已经有了。
- 只要用户有自己配置的,就以用户配置的优先。1.用户直接自己@Bean替换底层的组件 2. 用户去看这个组件的获取的配置文件什么值,就去配置文件修改该值。
3.3 最佳实践
-
引入场景依赖
-
查看自动配置了哪些组件
在配置文件中写入debug=true
-
是否需要修改
参照官方文档修改配置项 自定义加入或者替换组件