Spring、SpringBoot 框架功能学习

一. Spring核心功能

  1. **依赖注入(DI):**Spring的核心功能是通过依赖注入来管理对象之间的依赖关系。依赖注入是一种将对象的依赖关系注入到被依赖对象中的机制,它可以帮助降低对象之间的耦合度,使得代码更容易维护和测试。

  2. **控制反转(IoC):**IoC是Spring框架的核心思想之一。Spring的IoC容器管理和协调应用程序中的对象,而不是通过应用程序代码显式创建和依赖对象。Spring容器负责创建、配置和管理应用程序中的对象生命周期。它使用XML、注解或Java代码来定义和配置对象之间的依赖关系。通过使用IoC容器,开发人员可以更加专注于业务逻辑的实现,而不必关注对象的创建和依赖关系的维护。

  3. **面向切面编程(AOP):**Spring提供了面向切面编程的支持,使得开发人员可以更方便地将与业务逻辑无关的代码(如日志记录、事务管理等)进行解耦。通过AOP,开发人员可以将这些横切关注点进行统一管理,从而提高代码的可维护性和可测试性。

  4. **声明式事务管理:**Spring提供了一种声明式事务管理的机制,使开发人员能够以声明的方式管理事务。通过配置事务管理器和事务属性,开发人员可以轻松地对数据库操作进行事务管理,而无需编写复杂的事务管理代码。

  5. **数据访问抽象:**Spring提供了一套数据访问抽象,使得开发人员可以更方便地与不同的数据访问技术进行交互。无论是使用关系型数据库还是非关系型数据库,开发人员都可以通过Spring提供的数据访问抽象来统一访问数据。

  6. **Spring MVC框架:**Spring提供了一个基于MVC模式的Web框架,使得开发人员能够更轻松地开发和管理Web应用程序。Spring MVC框架提供了一套灵活而强大的机制来处理Web请求和生成响应,同时还提供了一些常用的功能,如表单处理、数据绑定、文件上传等。

总的来说,Spring的核心是一个轻量级的容器,它提供了依赖注入、面向切面编程、声明式事务管理、数据访问抽象和MVC框架等核心功能,这些功能使得开发人员可以更方便地开发和管理Java应用程序。

二. Spring与SpringBoot区别

  1. Spring是一个全面的框架,提供了一套丰富的功能来处理企业级应用开发中的各个方面,包括依赖注入、事务管理、安全性等。而Spring Boot旨在简化复杂性,通过自动配置和约定大于配置的原则,让开发者能够快速地构建应用程序。‌
  2. Spring需要大量的XML或Java配置来完成各种任务,而Spring Boot通过自动配置大大减少了这部分工作。
  3. ‌Spring Boot使用嵌入式的Tomcat或Jetty服务器,与应用程序一起打包,无需部署,这使得启动速度相对较快。
  4. ‌Spring Boot使用"Starter"来简化Maven配置,可以快速地添加各种功能和库。‌
  5. ‌Spring Boot专为构建微服务应用程序而设计。

详细解释Spring和SpringBoot的区别:

  1. 配置 ‌:
    1. Spring:需要大量的XML或Java配置来完成各种任务。
    2. Spring Boot:通过自动配置大大减少了配置工作,使得开发者可以专注于应用程序本身而不是配置。
  2. 启动速度 ‌:
    1. Spring:使用传统的服务器,需要部署。
    2. Spring Boot:使用嵌入式的Tomcat或Jetty服务器,与应用程序一起打包,无需部署,启动速度相对较快。
  3. 依赖管理 ‌:
    1. Spring:需要开发者手动管理依赖。
    2. Spring Boot:使用"starters"来简化Maven配置,可以快速地添加各种功能和库。

**三.**Spring与SpringMVC区别

  1. ‌SpringMVC是Spring框架中的一个模块,专注于Web应用程序的开发。它实现了模型-视图-控制器(MVC)设计模式,旨在简化Web应用的开发。SpringMVC处理Web请求,将请求映射到相应的处理器(Controller),处理器执行相应的业务逻辑,然后返回模型数据给视图层进行渲染。SpringMVC提供了丰富的注解支持,简化了配置过程,使得开发者可以快速开发出高效的Web应用。
  2. Spring是一个全面的企业应用开发框架,提供了包括Web开发在内的多种功能;而SpringMVC是Spring框架中的一个模块,专注于简化Web应用的开发,特别是通过实现MVC模式来处理Web请求。‌

四. SpringBoot与SpringCloud区别

  1. SpringBoot 是一个快速开发框架,它简化了传统MVC的XML配置,使配置变得更加方便、简洁。
  2. SpringCloud 是建立在SpringBoot上的服务框架,进一步简化了配置,它整合了一全套简单、便捷且通俗易用的框架,
    1. **Eureka(服务治理):**Eureka是Spring Cloud的服务治理组件,主要用于实现服务的注册与发现。通过Eureka,我们可以将微服务实例注册到中心化的服务注册表,并实现自动发现和动态负载均衡。Eureka支持高可用和可扩展的特性,能够有效地管理服务实例的故障转移和水平扩展。
    2. **Ribbon(负载均衡):**Ribbon是一个客户端负载均衡器,它提供了简单而强大的负载均衡功能。Ribbon可以与Eureka等服务发现组件集成,自动从服务注册表中获取服务实例的地址,并基于一定的算法进行负载均衡。这使得开发者能够更加专注于业务逻辑的实现,而不必花费过多精力在服务调用的细节上。
    3. **Hystrix(断路器):**Hystrix是Spring Cloud的断路器组件,主要用于防止级联故障和延迟。当某个服务出现故障时,Hystrix可以快速地切断对该服务的调用,从而避免故障的扩散。同时,Hystrix还提供了延迟容忍和容错机制,能够在网络延迟或服务故障时自动降级,保证系统的可用性和稳定性。
    4. **Zuul(网关):**Zuul是Spring Cloud的API网关组件,它提供了一种简单而有效的方式来管理和保护微服务的API接口。通过Zuul,我们可以将所有的API请求统一接入,进行安全认证、请求路由、负载均衡、熔断降级等操作。Zuul还支持动态路由和过滤器机制,可以根据实际需求进行自定义配置。
    5. **Config(配置中心):**Config是Spring Cloud的配置中心组件,它提供了一种集中式管理配置的方法。通过Config,我们可以将所有的配置信息统一存储在中心化的配置中心中,并动态地更新微服务的配置信息。这使得我们可以更加灵活地管理和维护微服务的配置信息,避免了配置不一致和重复配置的问题。

五. SpringCloud微服务组件

  1. **注册发现中心(Eureka,Nacos,Zookeeper,Consul):**它的作用是将同一个项目中的各个微服务注册到一起,从而使它们间相互认识。
  2. **服务调用负载(Ribbon,LoadBalancer):**Ribbon 可以在多个服务实例之间分配请求,以平衡负载并避免任何单个实例过载。
  3. 熔断器(Hystrix,Sentinel)。它的作用是当某个微服务瘫痪时可以将它从调用链中踢除出去,从而保证调用链上其他微服务的正常运作。
  4. 调用中心(Fegin,Open Feign)。它的作用是将各个微服务联系起来,使它们之间可以实现相互调用,由此组合成一个整体。
  5. 微服务网关(Zuul,GateWay)。它的作用是为不同的微服务提供一个统一的访问端口。
  6. 云配置中心(Cloud Config,Nacos)。它的作用是将一个项目所需的配置文件都放到云端统一管理,从而做到一个项目只有一套配置文件。
  7. 消息总线(Cloud Bus,Nacos)。它的作用是在修改配置文件时,可以在不停止服务运行的情况下重新加载配置。

六. Spring Bean生命周期

大致分为五个阶段:

  1. 实例化 Bean

  2. 对 Bean 当中的属性进行赋值

  3. 初始化 Bean

  4. 使用 Bean

  5. 销毁 Bean

详细阶段:

  1. Bean元信息配置阶段

  2. Bean元信息解析阶段

  3. 将Bean注册到容器中

  4. BeanDefinition合并阶段

  5. Bean Class加载阶段

  6. Bean实例化阶段(2个小阶段)

Bean实例化前阶段

Bean实例化阶段

  1. 合并后的BeanDefinition处理

  2. 属性赋值阶段(3个小阶段)

Bean实例化后阶段

Bean属性赋值前阶段

Bean属性赋值阶段

  1. Bean初始化阶段(5个小阶段)

Bean Aware接口回调阶段

Bean初始化前阶段

Bean初始化阶段

Bean初始化后阶段

  1. 所有单例bean初始化完成后阶段

  2. Bean的使用阶段

  3. Bean销毁前阶段

  4. Bean销毁阶段

1. Bean元信息配置阶段

1.1. Bean定义4种方式

1.1.1. API方式

Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构,不管是是通过xml配置文件的<Bean>标签,还是通过注解配置的@Bean,还是@Compontent标注的类,还是扫描得到的类,它最终都会被解析成一个BeanDefinition对象,最后我们的Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作。

1.1.2. Xml文件方式

Xml中的bean配置信息会被解析器解析为BeanDefinition对象,一会在第二阶段详解。

1.1.3. Properties文件的方式

将bean定义信息放在properties文件中,然后通过解析器将配置信息解析为BeanDefinition对象。

java 复制代码
employee.(class)=MyClass       // 等同于:<bean class="MyClass" />
employee.(abstract)=true       // 等同于:<bean abstract="true" />
employee.group=Insurance       // 为属性设置值,等同于:<property name="group" value="Insurance" />
employee.usesDialUp=false      // 为employee这个bean中的usesDialUp属性设置值,等同于:等同于:<property name="usesDialUp" value="false" />
 
1.1.4. 注解方式

使用 @Compontent 注解来定义一个bean,配置类中使用 @Bean 注解来定义bean

1.2. 总结

Bean注册者只识别 BeanDefinition 对象,不管什么方式最后都会将这些bean定义的信息转换为BeanDefinition对象,然后注册到Spring容器中

2. Bean元信息解析阶段

Bean元信息的解析就是将各种方式定义的bean配置信息解析为BeanDefinition对象。

3. 将Bean注册到容器中

通过 BeanDefinitionRegistry接口将 Bean注册、获取、移除等操作

4. BeanDefinition合并阶段

我们定义bean的时候有父子bean关系,此时子BeanDefinition中的信息是不完整的,比如设置属性的时候配置在父BeanDefinition中,此时子BeanDefinition中是没有这些信息的,需要将子bean的BeanDefinition和父bean的BeanDefinition进行合并,得到最终的一个RootBeanDefinition,合并之后得到的RootBeanDefinition包含bean定义的所有信息,包含了从父bean中继继承过来的所有信息,后续bean的所有创建工作就是依靠合并之后BeanDefinition来进行的。

5. Bean Class加载阶段

这个阶段就是将bean的class名称转换为Class类型的对象。BeanDefinition中有个Object类型的字段 beanClass,用来表示bean的class对象,通常这个字段的值有2种类型,一种是bean对应的Class类型的对象,另一种是bean对应的Class的完整类名,第一种情况不需要解析,第二种情况:即这个字段是bean的类名的时候,就需要通过类加载器将其转换为一个Class对象。此时会对阶段4中合并产生的RootBeanDefinition中的beanClass进行解析,将bean的类名转换为Class对象,然后赋值给beanClass字段。

6. Bean实例化阶段

这个过程会通过反射来调用bean的构造器来创建bean的实例。具体需要使用哪个构造器,Spring为开发者提供了一个接口,允许开发者自己来判断用哪个构造器。

7. 合并后的BeanDefinition处理

8. 属性赋值阶段(3个小阶段)

  1. 实例化后阶段,2. Bean属性赋值前处理 ,3. Bean属性赋值

9. Bean初始化阶段(5个小阶段)

  1. Bean Aware接口回调

  2. Bean初始化前操作

  3. Bean初始化操作

  4. Bean初始化后操作

  5. Bean初始化完成操作

10. 所有单例bean初始化完成后阶段

所有单例bean实例化完成之后,spring会回调下面这个接口:

java 复制代码
public interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}

11. Bean使用阶段

调用getBean方法得到了bean之后

12. Bean销毁前阶段

触发bean销毁的几种方式
  1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean

  2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons

  3. 调用ApplicationContext中的close方法

原文详情地址https://blog.csdn.net/qq_38361800/article/details/106418195

七. Spring循环依赖解决

第⼀级缓存: singletonObjects,⽤于保存实例化、注⼊、初始化完成的 bean 实例;
第⼆级缓存: earlySingletonObjects,⽤于保存实例化完成的 bean 实例;
**第三级缓存:**singletonFactories,用于保存 bean 创建⼯⼚,以便后面有机会创建代理对象。

执⾏逻辑:

1.先从一级缓存中找,找不到后去二级缓存找,还没有就去三级缓存找

  • ⼀级缓存作⽤: 变量命名为 singletonObjects,结构是 Map,它就是⼀个单例池, 将初始化好的对象放到⾥⾯,给其它线程使⽤,如果没有第⼀级缓存,程序不能保证 Spring 的单例属性
  • 三级缓存作⽤: 变量命名为 singletonFactories,结构是 Map>,Map 的 Value 是⼀个对象的代理⼯⼚,所以"三级缓存"的作⽤,其实就是⽤来存放对象的代 理⼯⼚
  • **⼆级缓存作⽤:**主要是⽤来存放对象⼯⼚⽣成的对象,这个对象可能是原对象,也可能是个代理对 象。
相关推荐
阿龟在奔跑1 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
飞滕人生TYF1 小时前
m个数 生成n个数的所有组合 详解
java·递归
代码小鑫1 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖1 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶1 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
周全全2 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
uzong2 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
AiFlutter2 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis
飞升不如收破烂~3 小时前
Spring boot常用注解和作用
java·spring boot·后端
秦老师Q3 小时前
Java基础第九章-Java集合框架(超详细)!!!
java·开发语言