Spring基础之六->Spring原理讲解

本文全面解析Spring框架的核心概念、模块组成及其优势,深入探讨IOC、DI原理,AOP实现机制,事务管理方式,以及Bean的生命周期等内容。

在这里插入图片描述

1、什么是Spring框架,Spring框架主要包含哪些模块

​ Spring是一个开源框架,Spring是一个轻量级的Java 开发框架。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的full-stack(一站式) 轻量级开源框架。

主要包含的模块:
在这里插入图片描述

2、Spring框架的优势

​ 1、Spring通过DI、AOP和消除样板式代码来简化企业级Java开发

​ 2、Spring框架之外还存在一个构建在核心框架之上的庞大生态圈,它将Spring扩展到不同的领域,如Web服务、REST、移动开发以及NoSQL

​ 3、低侵入式设计,代码的污染极低

​ 4、独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺

​ 5、Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦

​ 6、Spring的AOP允许将一些通用任务如安全、事务、日志等进行集中式处理,从而提供了更好的复用

​ 7、Spring的ORM和DAO提供了与第三方持久层框架的的良好整合,并简化了底层的数据库访问

​ 8、Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部

3、IOC和DI是什么?

​ 控制反转是就是应用本身不负责依赖对象的创建和维护,依赖对象的创建及维护是由外部容器负责的,这样控制权就有应用转移到了外部容器,控制权的转移就是控制反转。

​ 依赖注入是指:在程序运行期间,由外部容器动态地将依赖对象注入到组件中如:一般,通过构造函数注入或者setter注入。

4、描述下Spring IOC容器的初始化过程

​ Spring IOC容器的初始化简单的可以分为三个过程:

​ 第一个过程是Resource资源定位。这个Resouce指的是BeanDefinition的资源定位。这个过程就是容器找数据的过程,就像水桶装水需要先找到水一样。

​ 第二个过程是BeanDefinition的载入过程。这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDefition。

​ 第三个过程是向IOC容器注册这些BeanDefinition的过程,这个过程就是将前面的BeanDefition保存到HashMap中的过程。

5、BeanFactory 和 FactoryBean的区别?

  • BeanFactory是个Factory,也就是IOC容器或对象工厂,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的,提供了实例化对象和拿对象的功能。

    使用场景:

    • 从Ioc容器中获取Bean(byName or byType)
    • 检索Ioc容器中是否包含指定的Bean
    • 判断Bean是否为单例
  • FactoryBean是个Bean,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

    使用场景

    • ProxyFactoryBean

6、BeanFactory和ApplicationContext的异同

在这里插入图片描述
相同:

  • Spring提供了两种不同的IOC 容器,一个是BeanFactory,另外一个是ApplicationContext,它们都是Java interface,ApplicationContext继承于BeanFactory(ApplicationContext继承ListableBeanFactory。
  • 它们都可以用来配置XML属性,也支持属性的自动注入。
  • 而ListableBeanFactory继承BeanFactory),BeanFactory 和 ApplicationContext 都提供了一种方式,使用getBean(“bean name”)获取bean。

不同:

  • 当你调用getBean()方法时,BeanFactory仅实例化bean,而ApplicationContext 在启动容器的时候实例化单例bean,不会等待调用getBean()方法时再实例化。
  • BeanFactory不支持国际化,即i18n,但ApplicationContext提供了对它的支持。
  • BeanFactory与ApplicationContext之间的另一个区别是能够将事件发布到注册为监听器的bean。
  • BeanFactory 的一个核心实现是XMLBeanFactory 而ApplicationContext 的一个核心实现是ClassPathXmlApplicationContext,Web容器的环境我们使用WebApplicationContext并且增加了getServletContext 方法。
  • 如果使用自动注入并使用BeanFactory,则需要使用API注册AutoWiredBeanPostProcessor,如果使用ApplicationContext,则可以使用XML进行配置。
  • 简而言之,BeanFactory提供基本的IOC和DI功能,而ApplicationContext提供高级功能,BeanFactory可用于测试和非生产使用,但ApplicationContext是功能更丰富的容器实现,应该优于BeanFactory

7、Spring Bean 的生命周期?

在这里插入图片描述
总结:

(1)实例化Bean:

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。

(2)设置对象属性(依赖注入):

实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成依赖注入。

(3)处理Aware接口:

接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:

①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值;

②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。

③如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;

(4)BeanPostProcessor:

如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。

(5)InitializingBean 与 init-method:

如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

(6)如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;

以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

(7)DisposableBean:

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;

(8)destroy-method:

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

8、Spring AOP的实现原理?

​ Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

​ Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。

​ 如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

9、Spring 是如何管理事务的?

​ Spring事务管理主要包括3个接口,Spring的事务主要是由它们(PlatformTransactionManager,TransactionDefinition,TransactionStatus)三个共同完成的。

1. PlatformTransactionManager:事务管理器–主要用于平台相关事务的管理

主要有三个方法:

  • commit 事务提交;
  • rollback 事务回滚;
  • getTransaction 获取事务状态。

2. TransactionDefinition:事务定义信息–用来定义事务相关的属性,给事务管理器PlatformTransactionManager使用

这个接口有下面四个主要方法:

  • getIsolationLevel:获取隔离级别;
  • getPropagationBehavior:获取传播行为;
  • getTimeout:获取超时时间;
  • isReadOnly:是否只读(保存、更新、删除时属性变为false–可读写,查询时为true–只读)

事务管理器能够根据这个返回值进行优化,这些事务的配置信息,都可以通过配置文件进行配置。

3. TransactionStatus:事务具体运行状态–事务管理过程中,每个时间点事务的状态信息。

例如它的几个方法:

  • hasSavepoint():返回这个事务内部是否包含一个保存点,
  • isCompleted():返回该事务是否已完成,也就是说,是否已经提交或回滚
  • isNewTransaction():判断当前事务是否是一个新事务

声明式事务的优缺点

  • 优点:不需要在业务逻辑代码中编写事务相关代码,只需要在配置文件配置或使用注解(@Transaction),这种方式没有侵入性。
  • 缺点:声明式事务的最细粒度作用于方法上,如果像代码块也有事务需求,只能变通下,将代码块变为方法。

10、Spring 的不同事务传播行为有哪些,干什么用的?

在这里插入图片描述

11、Spring 中用到了那些设计模式?

  • 代理模式—在AOP中被用的比较多。
  • 单例模式—在spring配置文件中定义的bean默认为单例模式。
  • 模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
  • 工厂模式—BeanFactory用来创建对象的实例。
  • 适配器–spring aop
  • 装饰器–spring data hashmapper
  • 观察者-- spring 事件驱动模型
  • 回调–Spring Aware回调接口

12、Spring如何解决循环依赖?

https://blog.youkuaiyun.com/qq_36381855/article/details/79752689

13、bean的作用域

(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

(2)prototype:为每一个bean请求提供一个实例。

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

14、Spring框架中有哪些不同类型的事件

(1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

(2)上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

(3)上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

(4)上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

(5)请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

15、Spring通知有哪些类型

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

(2)返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

(3)抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。

(4)后通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

(5)环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。 环绕通知是最常用的一种通知类型。

16、Spring的自动装配

在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。

在Spring框架xml配置中共有5种自动装配:

(1)no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。

(2)byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。

(3)byType:通过参数的数据类型进行自动装配。

(4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。

(5)autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

基于注解的方式:

使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,<context:annotation-config />。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;

如果查询的结果不止一个,那么@Autowired会根据名称来查找;

如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

@Autowired可用于:构造函数、成员变量、Setter方法

注:@Autowired和@Resource之间的区别

(1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

(2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

<think>嗯,用户想深入了解Spring Cloud Gateway的内部工作原理和实现机制。从用户之前的提问来看,ta应该是个有经验的Java开发者,正在研究微服务架构中的网关技术。用户可能正在搭建或优化微服务架构,需要理解网关的核心机制来做出技术决策或解决实际问题。 用户提供的引用材料很丰富,主要涉及Spring Cloud Gateway的定位(替代Zuul)、核心依赖(WebFlux)、服务发现集成(Nacos、Kubernetes)和配置方式。不过用户明确要求的是"原理及工作机制",所以需要聚焦在架构设计层面而非配置细节。 首先需要解释清楚反应式编程模型这个基础,因为这是理解整个网关工作流的钥匙。WebFlux的非阻塞特性决定了网关的线程模型和请求处理方式,这点必须优先说明。然后要突出过滤器链这个核心设计模式,用户可能熟悉Servlet Filter,但反应式过滤器的差异需要特别强调。 路由机制部分需要区分配置阶段和运行时阶段:配置阶段强调Predicate和Filter的声明式特性,运行时阶段则要说明路由定位的流程。负载均衡作为高频使用功能,需要点明其通过ReactorLoadBalancer的集成位置。 用户可能还会关心实际性能表现,所以补充了工作流示例和性能优化点。最后的扩展机制说明是为了让用户知道如何定制网关,毕竟实际项目总会需要自定义Filter。 相关问题设计成阶梯式:从核心原理(WebFlux)到具体组件(Predicate),再到优化实践,最后是监控集成。这样用户可以根据当前需要选择深入方向。特别加入"与Zuul对比"的问题,因为引用[2]提到它是Zuul替代品,这个点开发者通常很关注。 需要避免陷入具体配置的讲解,比如引用[4]中的YAML示例就不展开,保持讨论在架构层面。但负载均衡的"lb://"语法值得提及,因为它是路由配置的关键符号。</think>Spring Cloud Gateway 的核心工作原理基于 **响应式编程模型(Spring WebFlux)** 和 **过滤器链(Filter Chain)** 设计,其工作机制可分解如下: --- ### 一、核心架构 1. **基于 WebFlux 的响应式引擎** Gateway 底层使用 **Project Reactor** 和 **Netty** 实现非阻塞 I/O,通过 `Reactor Netty` 处理 HTTP 请求,支持高并发场景[^1][^2]。 2. **路由(Route)核心组件** - **Predicate(断言)**:匹配请求的条件(如 Path、Header、Method 等),决定是否路由到目标 URI。 - **Filter(过滤器)**:处理请求和响应的逻辑单元(如添加 Header、重写路径、限流等)。 - **URI**:目标服务地址,支持 `lb://`(负载均衡)或 `http://`(直连)协议[^4]。 ```yaml spring: cloud: gateway: routes: - id: user_route uri: lb://user-service # 负载均衡到 user-service predicates: - Path=/api/users/** # 匹配路径 filters: - AddRequestHeader=X-Gateway, true # 添加请求头 ``` --- ### 二、请求处理流程 1. **路由匹配** 客户端请求 → Gateway 根据 `Predicate` 匹配路由规则 → 定位到目标 URI(如 `lb://service-name`)。 2. **过滤器链执行** 请求依次通过 **Gateway Filter** 链(Pre-Filters)→ 转发到目标服务 → 响应返回时通过 **Post-Filters** 处理[^1]。 ```mermaid graph LR A[客户端请求] --> B[Pre-Filters] B --> C{转发到目标服务} C --> D[目标服务处理] D --> E[Post-Filters] E --> F[返回响应] ``` 3. **负载均衡(Load Balancing)** 若 URI 为 `lb://service-name`,通过 **Spring Cloud LoadBalancer** 从注册中心(如 Nacos、Eureka)获取实例列表,按策略(轮询、随机等)选择实例[^3][^4]。 --- ### 三、关键机制详解 1. **过滤器类型** - **GatewayFilter**:作用于单个路由(如限流、重试)。 - **GlobalFilter**:全局生效(如认证、日志),通过 `@Order` 控制执行顺序。 ```java @Bean @Order(-1) public GlobalFilter authFilter() { return (exchange, chain) -> { // 身份验证逻辑 return chain.filter(exchange); }; } ``` 2. **动态路由** 支持通过 **Spring Cloud Config** 或 **Nacos 配置中心** 实时更新路由规则,无需重启网关。 3. **服务发现集成** 依赖 `spring-cloud-starter-kubernetes-discovery` 或 `spring-cloud-starter-alibaba-nacos-discovery`,自动同步注册中心的服务列表[^3][^4]。 --- ### 四、性能优化点 1. **使用缓存**:缓存路由定义,避免每次请求解析配置。 2. **精简 Filter 链**:减少非必要 Filter 的执行耗时。 3. **响应式编程优化**:避免在 Filter 中阻塞线程(如使用 `Mono.defer()` 处理异步操作)。 --- ### 五、扩展机制 1. **自定义 Predicate**:实现 `RoutePredicateFactory` 接口扩展匹配条件。 2. **自定义 Filter**:继承 `AbstractGatewayFilterFactory` 实现业务逻辑。 3. **集成 Sentinel**:通过 `spring-cloud-alibaba-sentinel-gateway` 实现熔断降级。 --- ### 工作流示例 ```mermaid sequenceDiagram Client->>+Gateway: HTTP 请求 /api/users Gateway->>Gateway: 匹配 Predicate (Path=/api/users/**) Gateway->>Gateway: 执行 Pre-Filters (认证、限流) Gateway->>LoadBalancer: 获取 user-service 实例 LoadBalancer-->>Gateway: 返回实例地址 (192.168.1.10:8080) Gateway->>user-service: 转发请求 user-service-->>Gateway: 返回响应 Gateway->>Gateway: 执行 Post-Filters (日志、修改响应头) Gateway-->>-Client: 返回最终响应 ``` --- **相关问题** 1. Spring WebFlux 的响应式模型如何提升 Gateway 的并发性能? 2. Gateway 的 GlobalFilter 与 Zuul 的 Filter 有何本质区别? 3. 如何实现动态路由更新而不重启网关服务? 4. Gateway 集成 Spring Cloud LoadBalancer 时如何自定义负载均衡策略? 5. 如何通过 Gateway 的 Filter 实现全链路灰度发布? 6. Gateway 与 Nacos 的服务发现集成机制是怎样的? 7. 如何监控 Gateway 的请求延迟和错误率? [^1]: Spring-cloud-gateway 源码浅析,基于 WebFlux 和 Filter Chain 架构。 [^2]: Spring-Cloud-Gateway 作为 Zuul 的替代方案,采用非阻塞式设计。 [^3]: 依赖 `spring-cloud-kubernetes-discovery` 实现 Kubernetes 服务发现。 [^4]: 通过 `lb://` 协议和 Nacos 实现负载均衡路由。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值