前言
由于部门业务调整,需要使用spring boot框架,以下是自学框架的笔记
本文参考哔哩哔哩SpringBoot最新教程IDEA版通俗易懂
一、什么是spring
轻量级开源框架
二、spring简化开发的策略
- 基于pojo轻量级和最小侵入式开发
- 基于ioc,依赖注入
- 面向切面编程和惯例进行声明式编程
- 通过切面和模板减少样式代码
三、什么是springboot
类似于springmvc的开发框架,特点是约定大于配置
从复杂的应用场景衍生出一种规范框架
四、微服务架构
独立每个功能,使每一个功能成为单独的服务
五、第一个springboot程序
创建springboot方法:
a.使用官网项目进行更改
b.使用idea开发
例子:
目录:
代码:
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/hello")
public class HelloController {
@GetMapping("/hello")
public Map<String, String> hello() {
HashMap<String, String> resultMap = new HashMap();
resultMap.put("data", "hello world");
return resultMap;
}
}
六、springboot自动装配原理
1.核心依赖
spring-boot-starter-parent
2.启动器
- 定义:springboot启动场景,例如spring-boot-starter-web会自动导入springboot web项目需要的所有依赖,springboot会把所有的功能场景变成启动器
- 位置:pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
3.主程序
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
注解:SpringBootApplication为复合注解
SpringBootConfiguration:springboot的配置
-
Configuration:spring配置类
EnableAutoConfiguration:自动配置
-
AutoConfigurationPackage:自动配置包 [@Import({Registrar.class}) 导入包注册]
-
@Import({AutoConfigurationImportSelector.class}):导入选择器
//AutoConfigurationImportSelector下,有方法 getAutoConfigurationEntry 获取候选类
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//获取候选的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
//获取候选的配置
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;
}
//获取标志了EnableAutoConfiguration的包
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
//类加载方法
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader;
if (classLoader == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
Map<String, List<String>> result = (Map)cache.get(classLoader);
if (result != null) {
return result;
} else {
HashMap result = new HashMap();
try {
Enumeration urls = classLoader.getResources("META-INF/spring.factories");
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
// 所有资源加载到配置类中
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryTypeName = ((String)entry.getKey()).trim();
String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
String[] var10 = factoryImplementationNames;
int var11 = factoryImplementationNames.length;
for(int var12 = 0; var12 < var11; ++var12) {
String factoryImplementationName = var10[var12];
((List)result.computeIfAbsent(factoryTypeName, (key) -> {
return new ArrayList();
})).add(factoryImplementationName.trim());
}
}
}
result.replaceAll((factoryType, implementations) -> {
return (List)implementations.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
});
cache.put(classLoader, result);
return result;
} catch (IOException var14) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var14);
}
}
}
META-INF/spring.factories:自动配置的核心文件
结论:所有自动配置类在启动时被扫描加载,自动配置类在spring.factories中,但不是所有的配置类都生效,导入了对应的start,就有启动器,有了启动器就会自动装配