1.创建一个springInitializr项目:构建子父类 子模块继承父模块的依赖
2.关于启动器:
SpringApplication.run(SonDemoApplication.class, args);
关于在配置application.properties里面加上:只有在bean使用是创建
spring.main.lazy-initialization=true
3.关于resource下面的application.properties跟.yml(约定>配置)
作用:修改springboot的默认值 除了.properties后缀名还可以写成.yml
两种配置的区别:
.properties->kv模式
server.port=8082
.yml->树型模式 可读性比较高
server:
port: 9999
外部约定配置的加载顺序:yml->yaml->properties(pom文件中starter-parent里有约定)
4.外部约定配置文件的顺序
resource里面的加载顺序优先级:高->低
直接子目录/config->项目根目录下面/config下面配置文件->项目根目录下面->/config下面配置文件->直接根目录下的配置文件
直接子目录java -jar parentdemo-0.0.1-SNAPSHOT.jar --server.port=9900
也可以java -jar parentdemo-0.0.1-SNAPSHOT.jar --spring.config.location=D:\config(使用命令行参数不会跟其他的配置文件参数互补)
5.profile文件的加载:不同环境中配置不同生效
在application.properties指定prod文件首先被加载
如果指定的bean被@Profile("prod")此bean生效,别的bean不生效
springboot所有配置文件的加载顺序:(低->高)
打包在jar中配置文件->打包在jar包中的profile->打包在jar包之外的配置文件->打包的jar之外的profile文件
6.配置文件读取方式 :(低->高)
a.默认属性(通过设置指定springApplication.setDefaultProperties)(会跟约定的配置文件进行互补)
b.@PropertySource("")(会跟约定的配置文件进行互且一定指定properties配置,yml是不行的)
c.约定的配置文件
d.操作的环境变量(idea上可以操作properties的路径或者windons的路径)(会跟约定配置文件不互补)
e.java系统属性 java -Dspringxxx
f.命令行参数
7.配置文件注入
a.可以通过@value+$直接绑定值
将yml映射到属性
user:
name: "lily"
实体对象(@ConfigurationProperties(prefix="user")user中属性全量赋上,支持松散绑定)
@Value($"user.name")
private String name;
属性引用:
user:
name: "lily"
memo: ${user.name}zhasd
随机数:
user:
name: "lily"
memo: ${random.value}
@ConfigurationProperties跟@Value差异
@ConfigurationProperties | @Value | |
绑定 | 批量注入 | 单个赋值 |
松散绑定 | 支持 | limit |
spel | 不支持 | 支持 |
自动提示 | 支持 | 不支持 |
JSR303数据校验 | 支持 | 不支持 |
8.自动配置读取原理
关于pom.xml:springboot默认做了很多东西启动8080端口等
<!--场景启动器:不同的场景启动器维护所有应用的依赖,简化开发
spring-boot-starter-web;使用springmvc构建web应用,使用tomcat作为默认的嵌入容器
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
一切都从启动类开始
@SpringBootApplication(scanBasePackages = "com.controller.Hello")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
启动注解@SpringBootApplication
@Target(ElementType.TYPE) //注解的作用域 设置当前注解可以标记在哪
@Retention(RetentionPolicy.RUNTIME) //注解的生存周期注解 编译的类以什么方式保留 会被jvm加载
@Documented //可以被文档化 javac doc会生成注解信息
@Inherited //注解用于标注一个父类的注解是否可以被子类继承
@SpringBootConfiguration //声明为一个配置类 proxyBeanMethods是否开启bean代理,默认是true,从IOC容器中取;如果是false则每次获取都是一个新的实例
@EnableAutoConfiguration //开启自动配置---这个将是我们研究的重点
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) //包扫描的规则
@SpringBootConfiguration:将当前类作为配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration
@EnableAutoConfiguration:告诉springboot自动配置类,开启自动配置
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //将当前配置类所在的包保存在BasePackage中,供spring内部使用
@Import(AutoConfigurationImportSelector.class) //会当前配置类保存到当前配置当中
public @interface EnableAutoConfiguration
关于AutoConfigurationImportSelector.class是实现DeferredImportSelector,首先回去看类是否有去实现这个类。如果没有实现了则Class<? extends Group> getImportGroup()
,将数组中的完整类名注册为bean,如果实现了则返回DeferredImportSelector自定义的类,最后是调用实现了process()->getAutoConfigurationEntity->getCandidateConfiguration获取所有配置类(自动配置类,整合第三方库做的一些默认配置),其次Group接口的selectImports()
getCandidateConfiguration()->getSpringFactoriestLoaderFactoryClass返回EnableAutoConfiguration.class()
getCandidateConfiguration()->factoryTypeName中org.springframework.boot.autoconfigure.EnableAutoConfiguration以这个完整类做过滤做自动配置类->loaFactoryName->loadSpringFactories去读取一个存放配置类的文件(MATAI-NFO/spring.factories(所有jar包中))
@ComponentScan:扫描包,无指定包,当前配置类的包为默认(TypeExcludeFilter.xml排除类,AutoConfigurationExcludeFilter.class排除自动配置类)
拿到所有自动配置类127个通过getConfigurationClassFilter().filter(configuartion)过滤到了23个startweb所需要的自动配置类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan
关于自动配置类的原理:
@Configuration(proxyBeanMethod=false):标记了该注解,spring底层会给配置创建cglib动态代理(代理方法的作用@bean会自动创建到ioc容器中,防止每次调用本类的bean方法,而重新创建对象,bean默认是单例的),false代表每次都会new一个对象
@EnableConfigurationProperties():启用在配置类中可以设置的属性对应的类
@Conditional:当前环境必须什么条件才起作用