2025年 Java 面试八股文(20w字)_java面试八股文-CSDN博客
三、JAVA框架
1.SpringMVC以及工作流程
Spring MVC 是 Spring 框架中用于构建 Web 应用程序的模块,基于 Model-View-Controller (MVC) 设计模式。其核心工作流程围绕 DispatcherServlet
(前端控制器)展开,协调各组件处理请求。
1. 用户发送请求
客户端(浏览器)通过 HTTP 协议发送请求到 Web 应用。
2. DispatcherServlet 接收请求
前端控制器 DispatcherServlet
是所有请求的入口,负责统一调度。
配置在 web.xml
或通过 Spring Boot 自动配置,拦截匹配的 URL 模式(如 /
)。
3. 确定处理器(HandlerMapping)
DispatcherServlet
查询已注册的 HandlerMapping 组件(如 RequestMappingHandlerMapping
)。
HandlerMapping 根据请求 URL 和配置(如 @RequestMapping
注解)找到对应的 Controller 方法。
4. 调用处理器适配器(HandlerAdapter)
HandlerAdapter(如 RequestMappingHandlerAdapter
)负责调用具体的 Controller 方法。
处理参数绑定、数据验证、返回值处理等逻辑。
5. 执行 Controller 方法
Controller 方法执行业务逻辑(调用 Service 层),生成 模型数据(Model)和 视图名称(View Name)。
支持多种返回类型:
ModelAndView:包含模型和视图名称。
String:直接返回视图名称。
@ResponseBody:直接返回数据(JSON/XML),跳过视图解析。
6. 处理返回值
视图解析:若返回视图名称,DispatcherServlet
调用 ViewResolver 解析为具体视图对象(如 JSP、Thymeleaf)。
数据转换:若返回 @ResponseBody
,使用 HttpMessageConverter(如 MappingJackson2HttpMessageConverter
)将数据转换为 JSON/XML。
7. 渲染视图
视图对象(如 InternalResourceView
)使用模型数据渲染页面,生成 HTML 响应。
8. 返回响应
DispatcherServlet
将渲染后的响应发送回客户端。
2.Spring或者SpringMVC中常用的注解
@Component
作用:通用注解,标记一个类为 Spring 管理的组件(Bean),会被自动扫描到 IoC 容器。
@Controller
作用:标记一个类为 控制器层(Web 层)组件,处理 HTTP 请求。
@Service
作用:标记一个类为 服务层(业务逻辑层)组件。
@Repository
作用:标记一个类为 持久层(数据访问层)组件,用于数据库操作。
@Autowired
作用:自动注入依赖的 Bean(按类型匹配)。//Spring 框架特有
@Resource
作用:自动注入依赖的 Bean。(优先按名称,其次按类型)//Java 标准
@Qualifier("beanName")
作用:按名称指定注入的 Bean,解决 @Autowired
类型冲突。
@RequestMapping
作用:映射 HTTP 请求路径到控制器方法。
@GetMapping
/ @PostMapping
作用:@RequestMapping
的快捷方式,分别对应 GET 和 POST 请求。
@PathVariable
作用:从 URL 路径模板中提取变量值。
@ResponseBody
作用:将方法返回值直接作为 HTTP 响应体(如 JSON/XML),而非视图名称。
@RequestParam
作用:从请求参数(URL 查询参数或表单数据)中提取值。
@RequestBody
作用:将 HTTP 请求体中的 JSON/XML 数据转换为 Java 对象。
@Param
作用:为 MyBatis Mapper 接口方法的参数命名,用于 XML 或注解 SQL 中引用。
3.SpringMVC如何返回JSON数据
Step1:在项目中加入json转换的依赖,例如jackson,fastjson,gson等
Step2:在请求处理方法中将返回值改为具体返回的数据的类型, 例如数据的集合类List<Employee>等
Step3:在请求处理方法上使用@ResponseBody注解
4.Spring
Spring 是一个开源框架,为简化企业级应用开发而生。Spring 可以是使简单的JavaBean 实现以前只有EJB 才能实现的功能。Spring 是一个 IOC 和 AOP 容器框架。
Spring 容器的主要核心是:
控制反转(IOC),传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者 getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring 提供的对象就可以了,这是控制反转的思想。
依赖注入(DI),spring 使用 javaBean 对象的 set 方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
面向切面编程(AOP),在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。AOP 底层是动态代理,如果是接口采用 JDK 动态代理,如果是类采用CGLIB 方式实现动态代理
5.SpringMVC:Spring 框架
- Spring MVC只有一个Servlet DispatcherServlet
是 基于 Servlet API 构建的 Web 框架,而 DispatcherServlet 是 Spring MVC 的核心前端控制器(Front Controller),负责协调整个请求处理流程
- 所有 HTTP 请求先到达 DispatcherServlet,由它统一分发到对应的组件(如 @Controller、HandlerMapping)
- 处理流程:
- 客户端发送请求,浏览器访问 http://localhost:8080/user。post 参数:username password age sex
- Tomcat 接收请求、发送到DispatcherServlet 。
- DispatcherServlet 调用 HandlerMapping 找到对应的控制器(@Controller)。通过 HandlerAdapter 执行控制器方法。DispatcherServlet 和控制器之间的适配
前台传过来的是框架定义:doPost(HttpServletRequest request,....)
用户自定义:UserController saveUser(User user)
需要HandlerAdapter 来适配上述两个接口
- Tomcat 调用 Servlet执行 doGet() 或 doPost() 方法。Service方法
- Servlet 处理请求执行业务逻辑,生成响应(如返回 "Hello, Tomcat!")。
- Tomcat 返回响应将结果发送给客户端(浏览器显示内容)。
- 看流程图 Springmvc工作流程
6.SpringBoot:脚手架
Spring springmvc mybatis tomcat
脚手架就是帮你“搭架子”的工具,
让你能站在一个合理的基础上专注盖楼(写业务代码),
而不是先花时间打地基(配环境)
约定优于配置,开箱即用
7.Servlet:服务器端程序
web开发:B/S servlet+tomat+jsp
静态页面 IIS
- Servlet用于处理客户端(如浏览器)的 HTTP 请求并生成动态响应。
它是 Java Web 开发的基础技术,运行在 Web 服务器(如 Tomcat、Jetty)中.1997年 IBM
- tomcat 是一个 开源的 Servlet 容器(Web 服务器),
实现了 Java Servlet 和 JSP 规范。
作用有:1、管理 Servlet 生命周期(初始化、调用、销毁)。
2、处理 HTTP 请求,将请求分发给对应的 Servlet。
3、提供 Web 服务(支持静态资源、动态 JSP 页面等)。1999年 war包
4、tomcat 是 Servlet 的运行容器(Servlet Container),
是Servlet规范的制定者。而 Servlet 是运行在 Tomcat 中的 Java 组件,
用于处理 HTTP 请求和响应。
- 工作流程(Tomcat + Servlet)看代码。service
- 客户端发送请求,浏览器访问 http://localhost:8080/hello。
- Tomcat 接收请求、解析 URL,查找匹配的 Servlet(如 HelloServlet)。xml配置文件
- Tomcat 调用 Servlet执行 doGet() 或 doPost() 方法。service方法
- Servlet 处理请求执行业务逻辑,生成响应(如返回 "Hello, Tomcat!")。
- Tomcat 返回响应将结果发送给客户端(浏览器显示内容)。
- 简单理解:Servlet = 服务员(处理请求)。
Tomcat = 餐厅(提供场地和管理服务员)。
浏览器 = 顾客(点餐并等待响应)。
- JSP是什么?Java和html的综合体
- Servlet的缺点是什么?
1、程序员开发效率低。2、配置复杂
- Servlet学习的必要性?
学习底层原理:理解 Web 请求处理机制。
极致性能优化:绕过框架开销,直接控制请求/响应。
8.Spring中常用的设计模式
代理模式——spring 中两种代理方式,若目标对象实现了若干接口,spring 使用jdk 的java.lang.reflect.Proxy类代理。若目标兑现没有实现任何接口,spring 使用 CGLIB 库生成目标类的子类。
单例模式——在 spring 的配置文件中设置 bean 默认为单例模式。
模板方式模式——用来解决代码重复的问题。
比如:RestTemplate、JmsTemplate、JpaTemplate
工厂模式——在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用同一个接口来指向新创建的对象。Spring 中使用 beanFactory 来创建对象的实例。
9.spring三级缓存
第一级缓存:存放完全初始化好的 Bean,后续所有请求直接使用成品
第二级缓存:临时存储提前暴露的 Bean 引用,避免重复执行 getEarlyBeanReference()
逻辑
第三级缓存:通过工厂对象延迟处理 AOP 代理等扩展逻辑,保证代理对象的正确性
10.循环依赖
循环依赖指两个或多个组件(如Spring中的Bean)相互直接或间接依赖,形成闭环。例如:
Bean A的初始化依赖Bean B
Bean B的初始化又依赖Bean A
此时Spring容器无法确定初始化顺序,形成死锁。
如何检测循环依赖
-
启动时异常:
Spring容器启动时会抛出BeanCurrentlyInCreationException
,明确提示循环依赖链(如提示Requested bean is currently in creation: Is there an unresolvable circular reference?
)。 -
代码检测:
在AbstractBeanFactory
的doGetBean
方法中,通过isPrototypeCurrentlyInCreation
检查原型作用域的循环依赖。 -
开发工具:
使用IDEA的依赖分析工具(右键类→Diagrams→Show Dependencies)可视化依赖关系。
如何解决循环依赖
解决流程(以A→B→A为例):
-
创建A实例(未初始化)→ 放入三级缓存
-
A发现依赖B → 触发B的创建
-
创建B实例(未初始化)→ 放入三级缓存
-
B发现依赖A → 从三级缓存获取A的工厂对象生成早期引用
-
B完成初始化 → A注入B的引用 → A完成初始化
多例(Prototype)为何无法解决循环依赖?
-
无缓存机制:
多例Bean每次getBean()
都会创建新实例,Spring不会缓存未初始化的多例Bean。 -
设计矛盾:
假设尝试解决A→B→A的循环依赖:-
创建A实例1 → 需要B实例1
-
创建B实例1 → 需要A实例2(新的多例实例)
-
创建A实例2 → 需要B实例2...
导致无限递归,最终StackOverflowError
。
-
-
Spring的防御:
在AbstractBeanFactory
中明确判断如果是原型作用域且正在创建,直接抛出异常:
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
总结
1,Spring创建 bean主要分为两个步骤,创建原始bean对象,接着去填充对象属性和初始化。
2,每次创建 bean之前,我们都会从缓存中查下有没有该bean,因为是单例,只能有一个。
3,当创建 A的原始对象后,并把它放到三级缓存中,接下来就该填充对象属性了,这时候发现依赖了B,接着就又去创建B,同样的流程,创建完B填充属性时又发现它依赖了A又是同样的流程,不同的是:这时候可以在三级缓存中查到刚放进去的原始对象A。
所以不需要继续创建,用它注入 B,完成 B的创建既然 B创建好了,所以 A就可以完成填充属性的步骤了,接着执行剩下的逻辑,闭环完成
Spring解决循环依赖依靠的是Bean的"中间态"这个概念,而这个中间态指的是已经实例化但还没初始化的状态—>半成品。实例化的过程又是通过构造器创建的,如果A还没创建好出来怎么可能提前曝光,所以构造器的循环依赖无法解决
其他衍生问题
问题1:为什么构造器注入属性无法解决循环依赖问题?
由于spring中的bean的创建过程为先实例化 再初始化(在进行对象实例化的过程中不必赋值)将实例化好的对象暴露出去,供其他对象调用,然而使用构造器注入,必须要使用构造器完成对象的初始化的操作,就会陷入死循环的状态
问题2:一级缓存能不能解决循环依赖问题? 不能
在三个级别的缓存中存储的对象是有区别的 一级缓存为完全实例化且初始化的对象 二级缓存实例化但未初始化对象 如果只有一级缓存,如果是并发操作下,就有可能取到实例化但未初始化的对象,就会出现问题
问题3:二级缓存能不能解决循环依赖问题?
理论上二级缓存可以解决循环依赖问题,但是需要注意,为什么需要在三级缓存中存储匿名内部类(ObjectFactory),原因在于 需要创建代理对象 eg:现有A类,需要生成代理对象 A是否需要进行实例化(需要) 在三级缓存中存放的是生成具体对象的一个匿名内部类,该类可能是代理类也可能是普通的对象,而使用三级缓存可以保证无论是否需要是代理对象,都可以保证使用的是同一个对象,而不会出现,一会儿使用普通bean 一会儿使用代理类
11.介绍一下Spring bean 的生命周期、注入方式和作用域
Bean的生命周期
(1)默认情况下,IOC容器中bean的生命周期分为五个阶段:
调用构造器 或者是通过工厂的方式创建Bean对象
给bean对象的属性注入值
调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.
使用
IOC容器关闭时, 销毁Bean对象.
(2)当加入了Bean的后置处理器后,IOC容器中bean的生命周期分为七个阶段:
调用构造器 或者是通过工厂的方式创建Bean对象
给bean对象的属性注入值
执行Bean后置处理器中的 postProcessBeforeInitialization
调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的.x
执行Bean的后置处理器中 postProcessAfterInitialization
使用
IOC容器关闭时, 销毁Bean对象
注入方式:
通过 setter 方法注入
通过构造方法注入
Bean的作用域
总共有四种作用域:
- Singleton 单例的
- Prototype 原型的
- Request
- Session
12.spring事务管理
Spring 的事务管理是其核心功能之一,用于处理数据库操作的原子性、一致性、隔离性和持久性(ACID)特性。
事务基础概念
-
ACID 特性:
-
原子性(Atomicity):事务要么全部成功,要么全部失败。
-
一致性(Consistency):事务前后数据状态一致。
-
隔离性(Isolation):事务间操作相互隔离,避免并发问题。
-
持久性(Durability):事务提交后,数据永久保存。
-
-
事务问题:
-
脏读、不可重复读、幻读、丢失更新。
-
事务的两种实现方式
声明式事务:通过注解(如 @Transactional
)或 XML 配置管理事务,基于 AOP(面向切面编程)动态代理,对业务代码侵入性低
编程式事务:通过 TransactionTemplate
或 PlatformTransactionManager
手动控制事务,适用于复杂业务逻辑
(1)声明式事务管理的定义:用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可,这样维护起来极其方便。
基于 TransactionInterceptor 的声明式事务管理:两个次要的属性: transactionManager,用来指定一个事务治理器, 并将具体事务相关的操作请托给它; 其他一个是 Properties 类型的transactionAttributes 属性,该属性的每一个键值对中,键指定的是方法名,方法名可以行使通配符, 而值就是表现呼应方法的所运用的事务属性。
(2)基于 @Transactional 的声明式事务管理:Spring 2.x 还引入了基于 Annotation 的体式格式,具体次要触及@Transactional 标注。@Transactional 可以浸染于接口、接口方法、类和类方法上。算作用于类上时,该类的一切public 方法将都具有该类型的事务属性。
(3)编程式事物管理的定义:在代码中显式挪用 beginTransaction()、commit()、rollback()等事务治理相关的方法, 这就是编程式事务管理。Spring 对事物的编程式管理有基于底层 API 的编程式管理和基于 TransactionTemplate 的编程式事务管理两种方式。
13.MyBatis中 #{}和${}的区别是什么
#{}是预编译处理,${}是字符串替换;
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理${}时,就是把${}替换成变量的值;
使用#{}可以有效的防止SQL注入,提高系统安全性。
14.Mybatis 中一级缓存与二级缓存
MyBatis的缓存分为一级缓存和 二级缓存。
一级缓存是SqlSession级别的缓存,默认开启。
二级缓存是NameSpace级别(Mapper)的缓存,多个SqlSession可以共享,使用时需要进行配置开启。
缓存的查找顺序:二级缓存 => 一级缓存 => 数据库
15.MyBatis如何获取自动生成的(主)键值
在<insert>标签中使用 useGeneratedKeys和keyProperty 两个属性来获取自动生成的主键值。
示例:
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
insert into names (name) values (#{name})
</insert>
16.简述Mybatis的动态SQL,列出常用的6个标签及作用
动态SQL是MyBatis的强大特性之一 基于功能强大的OGNL表达式。
动态SQL主要是来解决查询条件不确定的情况,在程序运行期间,根据提交的条件动态的完成查询
常用的标签:
<if> : 进行条件的判断
<where>:在<if>判断后的SQL语句前面添加WHERE关键字,并处理SQL语句开始位置的AND 或者OR的问题
<trim>:可以在SQL语句前后进行添加指定字符 或者去掉指定字符.
<set>: 主要用于修改操作时出现的逗号问题
<choose> <when> <otherwise>:类似于java中的switch语句.在所有的条件中选择其一
<foreach>:迭代操作
17.Mybatis 如何完成MySQL的批量操作
MyBatis完成MySQL的批量操作主要是通过<foreach>标签来拼装相应的SQL语句
例如:
<insert** id="insertBatch" >
insert into tbl_employee(last_name,email,gender,d_id) values
<foreach** collection="emps" item="curr_emp" separator=","**>
(#{curr_emp.lastName},#{curr_emp.email},#{curr_emp.gender},#{curr_emp.dept.id})
</foreach>
</insert>
18.谈谈怎么理解SpringBoot框架
Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。
Spring Boot的优点
独立运行
Spring Boot而且内嵌了各种servlet容器,Tomcat、Jetty等,现在不再需要打成war包部署到容器中,Spring Boot只要打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内。
简化配置
spring-boot-starter-web启动器自动依赖其他组件,简少了maven的配置。除此之外,还提供了各种启动器,开发者能快速上手。
自动配置
Spring Boot能根据当前类路径下的类、jar包来自动配置bean,如添加一个spring-boot-starter-web启动器就能拥有web的功能,无需其他配置。
无代码生成和XML配置
Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是Spring4.x的核心功能之一。
应用监控
Spring Boot提供一系列端点可以监控服务及应用,做健康检测。
Spring Boot缺点:
Spring Boot虽然上手很容易,但如果你不了解其核心技术及流程,所以一旦遇到问题就很棘手,而且现在的解决方案也不是很多,需要一个完善的过程。
19.Spring Boot 的核心注解是哪个 它主要由哪几个注解组成的
启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
1.@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。
2.@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,
如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
3.@ComponentScan:Spring组件扫描。
20.Spring Boot自动配置原理是什么
注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,
首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。
@EnableAutoConfiguration是实现自动配置的注解
@Configuration表示这是一个配置文件
-
启动类与注解
应用启动类使用@SpringBootApplication
注解,该注解组合了三个关键注解:-
@SpringBootConfiguration
:标记为配置类。 -
@ComponentScan
:启用组件扫描。 -
@EnableAutoConfiguration
:触发自动配置的核心注解。
-
-
@EnableAutoConfiguration的作用
该注解通过AutoConfigurationImportSelector
加载META-INF/spring.factories
文件中预定义的自动配置类。这些配置类包含大量@Bean
方法,但通过条件注解控制是否生效。 -
条件注解(Conditional)
自动配置类使用条件注解判断是否满足特定环境,例如:-
@ConditionalOnClass
:类路径存在指定类时生效。 -
@ConditionalOnMissingBean
:容器中无指定Bean时生效。 -
@ConditionalOnProperty
:配置属性满足条件时生效。
-
-
自动配置类的加载流程
-
步骤1:Spring Boot启动时扫描所有
META-INF/spring.factories
文件。 -
步骤2:筛选出
org.springframework.boot.autoconfigure.EnableAutoConfiguration
键下的所有配置类。 -
步骤3:通过条件注解过滤掉不满足当前环境的配置类(如无相关依赖、已有用户自定义Bean等)。
-
步骤4:将剩余的配置类加载到Spring容器中,创建对应的Bean。
-
-
Starter依赖与自动配置联动
Starter(如spring-boot-starter-web
)通过传递依赖引入特定库(如Tomcat、Spring MVC),自动配置类检测到这些依赖后,自动配置相关组件(如DispatcherServlet
)。 -
覆盖自动配置
用户可通过以下方式自定义配置:-
显式定义Bean:使用
@Bean
覆盖自动配置的Bean(条件注解@ConditionalOnMissingBean
将失效)。 -
配置文件:通过
application.properties
调整参数(如server.port=8081
)。 -
排除特定配置:使用
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
。
-
21.SpringBoot配置文件有哪些 怎么实现多环境配置
Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
bootstrap配置文件的特性:
bootstrap 由父 ApplicationContext 加载,比 applicaton 优先加载
bootstrap 里面的属性不能被覆盖
bootstrap 配置文件有以下几个应用场景:
使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
一些固定的不能被覆盖的属性;
一些加密/解密的场景;
提供多套配置文件,如:
applcation.properties
application-dev.properties
application-test.properties
application-prod.properties
22.SpringBoot和SpringCloud是什么关系
Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的开发工具;Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架; Spring Boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现,必须基于Spring Boot开发。
可以单独使用Spring Boot开发项目,但是Spring Cloud离不开 Spring Boot。
23.SpringCloud都用过哪些组件 介绍一下作用
Nacos--作为注册中心和配置中心,实现服务注册发现和服务健康监测及配置信息统一管理
Gateway--作为网关,作为分布式系统统一的出入口,进行服务路由,统一鉴权等
OpenFeign--作为远程调用的客户端,实现服务之间的远程调用
Sentinel--实现系统的熔断限流
Sleuth--实现服务的链路追踪
24.Nacos作用以及注册中心的原理
Nacos英文全称Dynamic Naming and Configuration Service,Na为naming/nameServer即注册中心,co为configuration即注册中心,service是指该注册/配置中心都是以服务为核心。
Nacos注册中心分为server与client,server采用Java编写,为client提供注册发现服务与配置服务。而client可以用多语言实现,client与微服务嵌套在一起,nacos提供sdk和openApi,如果没有sdk也可以根据openApi手动写服务注册与发现和配置拉取的逻辑。
服务注册原理
服务注册方法:以Java nacos client v1.0.1 为例子,服务注册的策略的是每5秒向nacos server发送一次心跳,心跳带上了服务名,服务ip,服务端口等信息。同时 nacos server也会向client 主动发起健康检查,支持tcp/http检查。如果15秒内无心跳且健康检查失败则认为实例不健康,如果30秒内健康检查失败则剔除实例。
25.Feign工作原理
主程序入口添加了@EnableFeignClients注解开启对FeignClient扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClient注解。当程序启动时,会进行包扫描,扫描所有@FeignClient的注解的类,并且讲这些信息注入Spring IOC容器中,当定义的的Feign接口中的方法被调用时,通过JDK的代理方式,来生成具体的RequestTemplate.当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,该对象封装HTTP请求需要的全部信息,如请求参数名,请求方法等信息都是在这个过程中确定的。然后RequestTemplate生成Request,然后把Request交给Client去处理,这里指的时Client可以时JDK原生的URLConnection,Apache的HttpClient,也可以时OKhttp,最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发器服务之间的调用。