springboot入门之自动装配
什么是SpringSpring是一个开源框架,2003年兴起的一个轻量级的Java开发框架,作者Rod Johnson.Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。Spring是如果简化Java开发的为了降低Java开发的复杂性,spring采用了以下4种关键策略1基于pojo的轻量级和最小侵入性编程;2通过控制反转(IOC),依赖注入(DI)和面向接口实现松耦合;3基于切面(
什么是Spring
Spring是一个开源框架,2003年兴起的一个轻量级的Java开发框架,作者Rod Johnson.
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
Spring是如果简化Java开发的
为了降低Java开发的复杂性,spring采用了以下4种关键策略
1基于pojo的轻量级和最小侵入性编程;
2通过控制反转(IOC),依赖注入(DI)和面向接口实现松耦合;
3基于切面(AOP)和惯例进行声明式编程;
4通过切面和模板减少样式代码
什么是springboot?
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
Spring boot的主要优点:
- 为所有的spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置
- 内嵌式容器简化web项目
- 没有冗余代码生成和xml配置的要求
什么是微服务
微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通,要说微服务架构,先得聊聊单体应用架构
单体架构
all in one
微服务架构
所谓微服务架构,就是打破之前all in one 的架构方式,把每个功能元素独立出来。把独立出来的功能元素动态组合,需要的功能元素才去拿来组合,需要多一些时间可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。
这样做的好处是:
1.节省了调用资源
2.每个功能元素的服务器都是一个可以替换的,可独立升级的软件代码。
https://martinfowler.com/articles/microservices.html
https://www.cnblogs.com/liuning8023/p/4493156.html
配置文件
Springboot使用一个全局的配置文件,配置文件名称是固定的
application.properties
语法结构:key=value
application.yml
语法结构:key:空格value
配置文件的作用:修改springboot自动配置的默认值,因为springboot在底层都给我们自动配置好了
Yaml配置时
@ConfigurationProperties作用:
将配置文件中配置的每一个属性的值,映射到这个组件中;告诉springboot 将本类中的所有属性和配置文件中相关的配置进行绑定
参数 perfix = “person” : 将配置文件中都person下面的所有属性一一对应。
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
Spel | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复制类型封装 | 支持 | 不支持 |
自动装配
Pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.4</version>
</parent>
spring-boot-dependencies:核心依赖在父工程中
我们在写或者引入一些springboot依赖的时候不需要指定版本,就是因为有这些版本仓库
启动器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
启动器:说白了就是springboot的启动场景
比如spring-boot-starter-web,他就是会帮我们自动导入web环境所有的依赖!
Springboot会将所有的功能场景,都变成一个个启动器;如果我们需要什么功能只需要找到对应的启动器
注解解析
@SpringBootApplication
@EnableAutoConfiguration
@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;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
spring.factories
META-INF/spring.factories:自动配置的核心文件
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);
}
}
}
Properties properties = PropertiesLoaderUtils.loadProperties(resource);//所有的资源加载到配置类中
思考:
这么多自动配置为什么有的没有生效,需要导入对应的start才能有作用?
核心注解@ConditionalOnXXX:如果这里面的条件都满足才生效
结论:
springboot所有的自动配置都在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功!
1springboot在启动时,从类路径下/META-INF/spring.factories获取EnableAutoConfiguration指定的值;
2将这些值作为自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置工作
3以前我们需要自己手动配置的东西,现在spring boot帮我们自动配置了
4整合JavaEE,解决方案和自动配置的东西都在spring-boot-autoconfigure.jar这包下
5它会把所有需要导入的组件,以全类名方式返回,这些组件就会被添加到容器;
6容器中也存在非常多的XXXAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件;并自动配置,
7有了自动配置类,免去了我们手动编写配置文件的工作
自动装配的原理精髓
- Springboot启动会加载大量的自动配置类;
- 我们看我们需要的功能有没有在springboot默认写好的自动配置当中;
- 我们再来看这个自动配置类中到底配置了那些组件;(只要我们要用的组件存在其中,我们就不需要在手动配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxProperties:封装配置文件中相关的属性
springboot Web 开发
1在springboot,我们可以使用以下方式处理静态资源
webjars -> localhost:8080/webjars/
public,static,/**,resource ->localhost:8080/
2优先级:resource>static(默认)>public
SpringMVC自动配置
通过研究mvc的自动配置,在springboot中有非常多的xxxConfiguration帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了
更多推荐
所有评论(0)