一、spring boot自动装配原理
pom.xml
spring-boot-dependencies 核心依赖在父工程中- 在写或者引入一些spring boot依赖的时候,不需要指定版本,因为有这些版本仓库
启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
启动器就是spring boot的启动场景,如spring-boot-starter-web,它会自动给我们导入web环境所有依赖!spring boot会将所有的功能场景,都变成一个个启动器,需要什么功能,找到对应的启动器即可!
主程序
//主程序入口,不能做任何更改
@SpringBootApplication //@SpringBootApplication标注这个类是一个springboot的应用,启动类下的所有资源被导入
public class SpringbootApplication {
public static void main(String[] args) {
//将springboot应用启动
SpringApplication.run( SpringbootApplication.class, args );
}
}
注解
@SpringBootConfiguration:springboot的配置
@Configuration:spring配置类
@Component:说明这也是一个spring组件
@EnableAutoConfiguration:自动配置
@AutoConfigurationPackage:自动配置包
@Import({Registrar.class}):自动配置 包注册
@Import({AutoConfigurationImportSelector.class}):自动配置导入选择
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取所有的配置
获取候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
META-INF/spring.factories :自动配置的核心文件
//将所有的配置资源加载到配置类中
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
小结:spring boot所有的自动配置都是在启动的时候扫描并加载;spring.factories所有的自动配置类都在这里面,但是要判单条件是否成立,才能判断是否生效,只需要导入对应的start,自动装配才会生效。
二、Run
是启动一个服务,而不是运行了main方法。
//主程序入口,不能做任何更改
@SpringBootApplication //@SpringBootApplication标注这个类是一个springboot的应用
public class SpringbootApplication {
public static void main(String[] args) {
//将springboot应用启动
SpringApplication.run( SpringbootApplication.class, args );
}
}
三、SpringBootApplication【谈谈spring boot的理解】
这个类主要做了四件事
- 判断应用的类型是普通的项目还是Web项目
- 查找并加载所有可用初始化器,设置到initializers属性中
- 找到所有应用程序监听器,设置到listeners中
- 推断并设置main方法的定义类,找到运行的主类
构造器
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
四、yaml语法
YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。
基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
server:
port: 8088
支持的数据类型
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 纯量(scalars):单个的、不可再分的值
YAML 对象
- 对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。
- 也可以使用 key:{key1: value1, key2: value2, ...}。
- 还可以使用缩进表示层级关系;
user:
name: 来一沓Java
age: 18
或行内写法
user: {name: 来一沓Java,age: 18}
注意:yaml语法对空格的要求非常严格!
五、通过yaml配置文件注入实现属性赋值
application.yaml
person:
name: 来一沓Java
age: 18
happy: false
birth: 2023/4/13
maps: {k1: v1,k2: v3}
list:
- code
- music
- girl
dog:
name: 小白
age: 2
导入文件处理器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
新建Dog和Person实体类
Dog类
@Component //将实体类添加到spring boot组件中
public class Dog {
private String name;
private Integer age;
public Dog() {
}
public Dog(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Person类
/*
@ConfigurationProperties(prefix = "person")的作用:
将配置文件中配置的每一个属性的值,映射到这个组件中。
告诉SpringBoot将本类中的所有属性和配置文件中相关配置进行绑定,
参数prefix = "person" :将配置文件中的person下面的所有属性一一对应
只有这个组件是容器的组件,才能使用容器提供的@ConfigurationProperties功能
*/
@Component//注册bean
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
public Person() {
}
public Person(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> list, Dog dog) {
this.name = name;
this.age = age;
this.happy = happy;
this.birth = birth;
this.maps = maps;
this.list = list;
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getHappy() {
return happy;
}
public void setHappy(Boolean happy) {
this.happy = happy;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getList() {
return list;
}
public void setList(List<Object> list) {
this.list = list;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", happy=" + happy +
", birth=" + birth +
", maps=" + maps +
", list=" + list +
", dog=" + dog +
'}';
}
}
测试是否注入成功
@SpringBootTest
class Springboot2ApplicationTests {
@Autowired
private Person person;
@Test
void contextLoads() {
System.out.println(person);
}
}
@PropertySources( value = "classpath:applications.properties")
加载指定配置文件,和@Value("${xxx}")配合使用