一、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: 来一沓Javaage: 18
或行内写法
user: {name: 来一沓Java,age: 18}
注意:yaml语法对空格的要求非常严格!
五、通过yaml配置文件注入实现属性赋值
application.yaml
person:name: 来一沓Javaage: 18happy: falsebirth: 2023/4/13maps: {k1: v1,k2: v3}list:- code- music- girldog: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;}@Overridepublic 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;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", happy=" + happy +", birth=" + birth +", maps=" + maps +", list=" + list +", dog=" + dog +'}';}
}
测试是否注入成功
@SpringBootTest
class Springboot2ApplicationTests {@Autowiredprivate Person person;@Testvoid contextLoads() {System.out.println(person);}}
@PropertySources( value = "classpath:applications.properties")
加载指定配置文件,和@Value("${xxx}")配合使用