当前位置: 首页 > news >正文

网站被攻击空间关了怎么办英语网站建设费用

网站被攻击空间关了怎么办,英语网站建设费用,网站的切换语言都是怎么做的,注册公司需要交多少税Spring Cloud OpenFeign 是一个声明式的 Web 服务客户端,它通过使用注解来简化 HTTP API 的调用过程,使得编写 Web 服务客户端变得更加简单。OpenFeign 可以帮助我们快速地集成 RESTful 服务,并且可以方便地与 Spring Cloud 生态系统中的其他…

Spring Cloud OpenFeign 是一个声明式的 Web 服务客户端,它通过使用注解来简化 HTTP API 的调用过程,使得编写 Web 服务客户端变得更加简单。OpenFeign 可以帮助我们快速地集成 RESTful 服务,并且可以方便地与 Spring Cloud 生态系统中的其他组件(如 Eureka、Ribbon、LoadBalancer 等)一起使用。

主要特性

• 声明式 REST 客户端:只需创建一个接口并用注解来配置它,就可以轻松实现对其他 HTTP 服务的绑定,而不需要手动编写大量的模板代码。
• 易于集成:能够很好地与其他 Spring Cloud 组件集成,比如服务发现( Eureka )、负载均衡( Ribbon / LoadBalancer )等。
• 灵活的配置:支持自定义编码器、解码器、错误处理器等,以满足不同的需求。
• 支持多种HTTP方法:支持 GET 、 POST 、 PUT 、 DELETE 、文件上传下载等功能。

简单使用示例

pom.xml 添加依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

在主类或者配置类上添加 @EnableFeignClients 注解来启用 Feign 客户端支持:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
public class FeignApplication {public static void main(String[] args) {SpringApplication.run(FeignApplication.class, args);}
}

定义 Feign 客户端接口:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;// 使用 @FeignClient 注解指定要调用的服务名称;若不依赖服务发现机制(如 Eureka),则需要配置 url    
@FeignClient(name = "greeting-service", url = "http://localhost:8090")
public interface GreetingServiceClient {@GetMapping("/api/greeting")String getGreeting();
}

使用 Feign 客户端:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class GreetingServiceImpl implements GreetingService {private final GreetingServiceClient greetingServiceClient;@Autowiredpublic GreetingServiceImpl(GreetingServiceClient greetingServiceClient) {this.greetingServiceClient = greetingServiceClient;}@Overridepublic String getGreeting() {// 直接使用 Feign 客户端return greetingServiceClient.getGreeting();}
}

核心原理

Spring Cloud OpenFeign 的核心实现是 声明式 REST 客户端 和 动态代理机制 。

核心组件
• @EnableFeignClients:这个注解用于启动 Feign 客户端的支持。在 Spring Boot 应用中,当你添加了这个注解后,Spring 会扫描指定包下的所有带有 @FeignClient 注解的接口,并为它们创建代理对象。
• @FeignClient:通过该注解定义一个 Feign 客户端,可以指定服务名(用于服务发现)、URL、编码器、解码器等属性。每个被标记的接口都会被增强生成 JDK 动态代理对象,实际请求会通过这些动态代理对象发送出去。
• Feign.Builder:Feign 的核心构建者类,它负责根据配置创建具体的 Feign 客户端实例。Spring Cloud 对默认的 Builder 进行了扩展,加入了负载均衡( Ribbon / LoadBalancer )、熔断器( Hystrix )等功能。
• LoadBalancerFeignClient:当与 Spring Cloud LoadBalancer 集成时,OpenFeign 使用的是一种特殊的服务请求客户端 —— LoadBalancerClient,它能够利用 Ribbon / Spring Cloud LoadBalancer 提供的负载均衡策略来选择服务实例进行调用。
• Decoder, Encoder, Logger, ErrorDecoder 等:这些是Feign的内部组件,分别用于处理响应的反序列化、请求的序列化、日志记录以及错误处理等功能。Spring Cloud 允许开发者自定义这些组件的行为。

工作流程
• 1、初始化: 在 Spring 容器启动期间,Spring Cloud 会扫描所有标注有@FeignClient的接口,为它们生成 JDK 动态代理对象,然后注入到 Spring 容器中。
• 2、创建Feign客户端: 利用 Feign.builder() 方法结合各种配置(如编码器、解码器、拦截器、接口注解配置等),构造出 Feign 动态代理客户端。如果整合了负载均衡器,则会使用 LoadBalancerClient 作为最终的客户端实现。
• 以 spring-cloud-starter-openfeign 包的 4.2.1 版本源码为例:

public class FeignClientFactoryBeanimplements FactoryBean<Object>, InitializingBean, ApplicationContextAware, BeanFactoryAware {/*** FeignClientFactoryBean 的 getObject() 方法是 Spring 容器用来获取由该工厂 Bean 创建的 Feign 客户端实例的方法。* getObject() 方法最终返回的是一个动态代理对象,这个对象实现了 @FeignClient 定义的接口,并能够将接口方法调用转换为 HTTP 请求*/@Overridepublic Object getObject() {return getTarget();}/*** 创建并返回一个 Feign 客户端实例*/@SuppressWarnings("unchecked")<T> T getTarget() {// 获取 FeignClientFactory 实例FeignClientFactory feignClientFactory = beanFactory != null ? beanFactory.getBean(FeignClientFactory.class): applicationContext.getBean(FeignClientFactory.class);// 使用 FeignClientFactory 构建 Feign.Builder 实例 (代码见后)Feign.Builder builder= feign(feignClientFactory);// 如果 URL 未提供且不在配置中可用,则尝试通过负载均衡选择实例if (!StringUtils.hasText(url) && !isUrlAvailableInConfig(contextId)) {if (LOG.isInfoEnabled()) {LOG.info("For '" + name + "' URL not provided. Will try picking an instance via load-balancing.");}if (!name.startsWith("http://") && !name.startsWith("https://")) {url = "http://" + name;} else {url = name;}url += cleanPath();// 通过负载均衡创建客户端动态代理实例 (代码见后)return (T) loadBalance(builder, feignClientFactory, new HardCodedTarget<>(type, name, url));}// 否则使用固定 URL 创建客户端if (StringUtils.hasText(url) && !url.startsWith("http://") && !url.startsWith("https://")) {url = "http://" + url;}// 获取服务请求客户端:// 1、如果没有额外引入任何 HTTP 客户端库(如 Apache HttpClient 或 OkHttp),// 并且也没有启用负载均衡组件(Ribbon 或 Spring Cloud LoadBalancer),// 那么默认使用的 Client 是 Feign 自带的基于 HttpURLConnection 的实现。// 2、如果启用了负载均衡组件,则使用的 Client 默认是 FeignBlockingLoadBalancerClient(未开启失败重试时)Client client= getOptional(feignClientFactory, Client.class);if (client != null) {// 如果启用负载均衡组件(Spring Cloud LoadBalancer),但由于这里不需要负载均衡,// 所以通过 getDelegate() 获取到具体的 HTTP 请求客户端(比如 HttpURLConnection)即可if (client instanceof FeignBlockingLoadBalancerClient) {// not load balancing because we have a url,// but Spring Cloud LoadBalancer is on the classpath, so unwrapclient = ((FeignBlockingLoadBalancerClient) client).getDelegate();}if (client instanceof RetryableFeignBlockingLoadBalancerClient) {// not load balancing because we have a url,// but Spring Cloud LoadBalancer is on the classpath, so unwrapclient = ((RetryableFeignBlockingLoadBalancerClient) client).getDelegate();}builder.client(client);}// 应用自定义构建器定制化applyBuildCustomizers(feignClientFactory, builder);// 获取 Targeter 实例,并使用它来创建目标客户端动态代理实例Targeter targeter= get(feignClientFactory, Targeter.class);return targeter.target(this, builder, feignClientFactory, resolveTarget(feignClientFactory, contextId, url));}/*** 创建并返回一个已配置好的 Feign.Builder 实例*/protected Feign.Builder feign(FeignClientFactory context) {FeignLoggerFactory loggerFactory= get(context, FeignLoggerFactory.class);Logger logger= loggerFactory.create(type);// @formatter:offFeign.Builder builder= get(context, Feign.Builder.class)// required values// 设置日志记录器,用于输出请求/响应详情.logger(logger)// 将 Java 对象编码为 HTTP 请求体(如 JSON、XML)。默认实现是 SpringEncoder,使用 Spring MVC 的 HttpMessageConverter。.encoder(get(context, Encoder.class))// Decoder:将 HTTP 响应体解码为 Java 对象。默认实现是 SpringDecoder,同样基于 HttpMessageConverter。.decoder(get(context, Decoder.class))// Contract:负责解析接口上的注解(如 @RequestMapping, @GetMapping 等)。默认是 SpringMvcContract,支持 Spring MVC 注解风格。.contract(get(context, Contract.class));// @formatter:on// 设置重试策略(Retryer)、错误处理器(ErrorDecoder)、请求拦截器(RequestInterceptor)、连接超时等配置项// 所有这些配置都支持用户自定义覆盖,默认值来自 Spring Boot 自动配置configureFeign(context, builder);return builder;}/*** 通过负载均衡创建客户端动态代理实例* @param builder 已配置好的 Feign.Builder 实例* @param context FeignClientFactory,用于从 Spring 容器中获取 Bean* @param target 一个封装了目标服务名称和 URL 的对象(通常是服务名,例如 http://service-name)*/protected <T> T loadBalance(Feign.Builder builder, FeignClientFactory context, HardCodedTarget<T> target) {// 获取服务请求客户端:// 如果启用了负载均衡组件,则使用的 Client 默认是 FeignBlockingLoadBalancerClient(未开启失败重试时)// FeignBlockingLoadBalancerClient 内会通过负载均衡获取一个服务实例,把服务名替换为真实IP和端口号,再发起 HTTP 请求。Client client = getOptional(context, Client.class);if (client != null) {// 设置 HTTP 请求客户端builder.client(client);// 应用额外定制化配置applyBuildCustomizers(context, builder);// 获取 TargeterTargeter targeter = get(context, Targeter.class);// 创建动态代理实例return targeter.target(this, builder, context, target);}throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?");}}public class ReflectiveFeign<C> extends Feign {// FeignClientFactoryBean 中的 targeter.target(...) 最终都会调用到 ReflectiveFeign.newInstance(...) 方法创建动态代理对象@SuppressWarnings("unchecked")public <T> T newInstance(Target<T> target, C requestContext) {TargetSpecificationVerifier.verify(target);Map<Method, MethodHandler> methodToHandler =targetToHandlersByName.apply(target, requestContext);InvocationHandler handler= factory.create(target, methodToHandler);// 最终返回的是一个 JDK 动态代理对象T proxy=(T)Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[] {target.type()}, handler);for (MethodHandler methodHandler : methodToHandler.values()) {if (methodHandler instanceof DefaultMethodHandler) {((DefaultMethodHandler) methodHandler).bindTo(proxy);}}return proxy;}}
public class FeignBlockingLoadBalancerClient implements Client {/*** 真正执行 HTTP 请求的底层客户端(如 Apache HttpClient、OkHttp、JDK HttpURLConnection 等)* FeignBlockingLoadBalancerClient 是一个装饰器模式的应用,它将实际请求委托给这个 delegate 执行*/private final Client delegate;/*** 用于服务发现和实例选择的负载均衡客户端* Spring Cloud 2020 之前的旧版本是 RibbonLoadBalancerClient* Spring Cloud 2020 之后的新版本是 BlockingLoadBalancerClient*/private final LoadBalancerClient loadBalancerClient;// (省略其他)...// 执行 HTTP 请求public Response execute(Request request, Request.Options options) throws IOException {// 将请求的 URL 解析为 URIfinal URI originalUri = URI.create(request.url());// 提取主机名作为 serviceId(即服务名称),比如 "order-service"String serviceId = originalUri.getHost();Assert.state(serviceId != null, "Request URI does not contain a valid hostname: " + originalUri);// 获取负载均衡策略使用的“hint”,通常是从请求头中提取的路由提示信息,比如可以基于请求头指定调用某个区域的服务实例String hint = getHint(serviceId);// 构建负载均衡请求上下文,request 里会包含请求体、头、方法等信息。DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(buildRequestData(request), hint));// 生命周期方法回调Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),RequestDataContext.class, ResponseData.class, ServiceInstance.class);supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));// 根据服务名称,选取服务实例// choose() 方法背后调用了 Ribbon 或 Spring Cloud LoadBalancer 的负载均衡策略算法(如轮询、随机、权重等)ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(instance);// 如果没有找到可用服务实例,构造一个 503 响应返回,同时通知生命周期处理器请求失败if (instance == null) {String message = "Load balancer does not contain an instance for the service " + serviceId;supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.DISCARD, lbRequest, lbResponse)));return Response.builder().request(request).status(HttpStatus.SERVICE_UNAVAILABLE.value()).body(message, StandardCharsets.UTF_8).build();}// 重构 URL:使用选中的 ServiceInstance 替换原始 URL 中的 host 部分。// 例如把 http://order-service/api/order/1 变成 http://192.168.1.10:8080/api/order/1String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();Request newRequest = buildRequest(request, reconstructedUrl, instance);// 通过底层的 HTTP 客户端(delegate)发送请求,并通知生命周期处理器执行回调方法 return executeWithLoadBalancerLifecycleProcessing(delegate, options, newRequest, lbRequest, lbResponse,supportedLifecycleProcessors);}
}

• 3、发起HTTP请求: 应用代码从 Spring 容器中获取到的 Feign 客户端,实际上是上面步骤 2 构造出来的 JDK 动态代理。当程序中调用 Feign 客户端的方法时,实际上是在调用由 JDK 动态生成的代理对象的方法,这个代理对象会将方法调用转换为 HTTP 请求,然后通过 HTTP 客户端发送出去。
• 4、响应处理: 收到响应后,相应的解码器会被用来解析响应内容,并将其转换为目标方法的返回值类型。

工作流程总结

在这里插入图片描述

Feign 与 Ribbon 整合的完整流程:
在这里插入图片描述
Feign 与 Spring Cloud LoadBalancer 整合的完整流程:
在这里插入图片描述

版本注意
Spring Cloud 从 2020.0.0 版本( Ilford 版本)开始,官方宣布不再对 Feign 进行维护和支持,并推荐使用 OpenFeign 作为替代方案。2020 版本后若要继续使用 Feign,依赖包需要从原来的 spring-cloud-starter-feign 替换为 spring-cloud-starter-openfeign 。

OpenFeign 是 Feign 的一个开源分支,将继续得到维护和支持,并且兼容 Spring Cloud生态系统。 OpenFeign 虽然核心上不直接包含与 Spring Cloud 组件(如 Eureka、Ribbon、Hystrix)的良好集成,但是可以通过配置来实现类似的集成效果,并且由于其灵活性,可以更容易地与其他工具和服务整合。

同时,Spring Cloud 从 2020.0.0 版本( Ilford 版本)开始也正式移除了对 Ribbon 的支持,在这个版本及之后的版本中,Ribbon 不再作为默认的客户端负载均衡器包含在 Spring Cloud 的发布版中,取而代之的是 Spring Cloud LoadBalancer 。

版本差异总结:

• Spring Cloud 2020.x 及之后:Feign(原生)已停止维护,默认使用 OpenFeign,而 OpenFeign 默认使用 Spring Cloud LoadBalancer。
• 旧版本(如 Spring Cloud Hoxton):Feign 和 OpenFeign 均默认使用 Ribbon 作为负载均衡组件。

http://www.dtcms.com/a/430075.html

相关文章:

  • 备案网站代理商前端技术
  • 做庭院景观的那个网站推广好国外网站免费dns
  • 合肥网站制作公司有哪些公司做外贸比较好的网站
  • 企业网站包括哪些南通wap网站建设
  • 网站托管运营金乡网站建设哪家好
  • 遵义网站网站建设抖音广告推广
  • 成都建设企业网站百度一下 你就知道官网
  • 网页设计视频网站建设网站开发方法是什么
  • 网站开发培训要多少钱长沙公众号开发公司
  • 响应式网站是wordpress加载插件
  • 在国外社交网站做产品推广wordpress国外主题网站模板
  • 昆明做网站魄罗科技wordpress主题php7
  • 网站不收录北京seo教师
  • 三明商城网站开发设计wordpress国主题
  • dede网站不能够生成程序员和软件开发的区别
  • 网站开发都有什么端以美食为主的网站栏目怎么做
  • 关于网站建设的英文文章开源零代码平台
  • 网站设计毕业设计论文怎么用抓爬工具做网站
  • 网站页面由什么构成石家庄万达网站制作
  • 网站 优点百度搜索热度排名
  • 南宁 网站开发合肥中小型企业网站建设方案模板
  • 综合购物网站排名网站建设以推广
  • 为网站网站做宣传建筑公司网址大全
  • 手机wap网站怎样从微信公众号打开深圳建设网招标公告
  • 微信彩票网站网站建设有没有公司做农副产品网站的
  • 专业重庆房产网站建设天津河西做网站贵吗
  • 单页网站建站网络推广软件全邀zjkwlgs
  • 巨野县建设局网站做外贸业务员需要什么条件
  • 景区网站建设费用访问不到自己做的网站
  • 钦州网站网站建设企业电话名录