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

java注解@FeignClient修饰的类路径不在spring boot入口类所在的包下,有哪几种处理方式?

一、注解@EnableFeignClients

修饰在spring boot入口类,使得openfeign的@FeignClient注解生效。

我们进一步看看注解@EnableFeignClients的使用方式。

String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] clients() default {};

在这里插入图片描述

  • 其实已经能满足我们的需求了,但是,很多业务方在引用的时候,往往是懒得去配置。

像下面这样,多写一个配置参数就算输了。

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

你本来写好了使用文档,像下面这样使用:

// AuthServiceClient类所在的包名是com.xxx.ddd.jwt.feign
// 当前用户服务的@FeignClient所在包路径是com.xxx.user.service.feign
@SpringCloudApplication
@EnableFeignClients(basePackages = {com.xxx.user.service.feign,com.xxx.ddd.jwt.feign})public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}
  • 可惜,使用的人,都嫌弃这配置过于多了,压根就不想关心@EnableFeignClients的属性应该写些啥。

所以,本文就简单说下,推荐的一个方式,让使用方不用去关心额外的包路径。

二、类的结构

  • com.xxx.ddd.jwt
    • JwtFeignPackageClass.java
    • feign
      • AuthServiceClient.java

保证注解@EnableFeignClients必须攘括了@FeignClient的包路径。

在这里插入图片描述

三、AuthServiceClient.java

package com.xxx.ddd.jwt.feign;import org.springframework.cloud.openfeign.FeignClient;@FeignClient(name = "auth-service")
public interface AuthServiceClient {// TODO 写你自己的接口
}

四、JwtFeignPackageClass.java

注意,该类的路径是在@FeignClient的包路径下,或者其上一级包路径。

package com.xxx.ddd.jwt;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.openfeign.EnableFeignClients;/*** jwt feign注解生效的包路径.** @author xxx*/
@EnableFeignClients
public class JwtFeignPackageClass {
}

五、总结

  • org.springframework.cloud.openfeign.FeignClientsRegistrar
class FeignClientsRegistrarimplements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware{}

梳理下它的主要代码

@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {registerDefaultConfiguration(metadata, registry);registerFeignClients(metadata, registry);}
  • 扫描注解EnableFeignClients的类所在包下的所有注解FeignClient
	public void registerFeignClients(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {ClassPathScanningCandidateComponentProvider scanner = getScanner();scanner.setResourceLoader(this.resourceLoader);Set<String> basePackages;Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableFeignClients.class.getName());AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(FeignClient.class);final Class<?>[] clients = attrs == null ? null: (Class<?>[]) attrs.get("clients");if (clients == null || clients.length == 0) {scanner.addIncludeFilter(annotationTypeFilter);basePackages = getBasePackages(metadata);}else {final Set<String> clientClasses = new HashSet<>();basePackages = new HashSet<>();for (Class<?> clazz : clients) {basePackages.add(ClassUtils.getPackageName(clazz));clientClasses.add(clazz.getCanonicalName());}AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {@Overrideprotected boolean match(ClassMetadata metadata) {String cleaned = metadata.getClassName().replaceAll("\\$", ".");return clientClasses.contains(cleaned);}};scanner.addIncludeFilter(new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));}for (String basePackage : basePackages) {Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);for (BeanDefinition candidateComponent : candidateComponents) {if (candidateComponent instanceof AnnotatedBeanDefinition) {// verify annotated class is an interfaceAnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();Assert.isTrue(annotationMetadata.isInterface(),"@FeignClient can only be specified on an interface");Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(FeignClient.class.getCanonicalName());String name = getClientName(attributes);registerClientConfiguration(registry, name,attributes.get("configuration"));registerFeignClient(registry, annotationMetadata, attributes);}}}}
  • 拼接对象FeignClientFactoryBean的属性,利用BeanDefinitionReaderUtils.registerBeanDefinition注册到spring容器
	private void registerFeignClient(BeanDefinitionRegistry registry,AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {String className = annotationMetadata.getClassName();BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(FeignClientFactoryBean.class);validate(attributes);definition.addPropertyValue("url", getUrl(attributes));definition.addPropertyValue("path", getPath(attributes));String name = getName(attributes);definition.addPropertyValue("name", name);String contextId = getContextId(attributes);definition.addPropertyValue("contextId", contextId);definition.addPropertyValue("type", className);definition.addPropertyValue("decode404", attributes.get("decode404"));definition.addPropertyValue("fallback", attributes.get("fallback"));definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);String alias = contextId + "FeignClient";AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();beanDefinition.setAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE, className);// has a default, won't be nullboolean primary = (Boolean) attributes.get("primary");beanDefinition.setPrimary(primary);String qualifier = getQualifier(attributes);if (StringUtils.hasText(qualifier)) {alias = qualifier;}BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,new String[] { alias });BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);}

openfeign的@FeignClient封装了http请求的入参和出参,并且支持okhttp/httpclient/HttpsURLConnection等调用方式。

相关文章:

java注解@FeignClient修饰的类路径不在spring boot入口类所在的包下,有哪几种处理方式?

一、注解EnableFeignClients 修饰在spring boot入口类&#xff0c;使得openfeign的FeignClient注解生效。 我们进一步看看注解EnableFeignClients的使用方式。 String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] clie…...

神经网络随记-参数矩阵、剪枝、模型压缩、大小匹配、、

神经网络的参数矩阵 在神经网络中&#xff0c;参数矩阵是模型学习的关键部分&#xff0c;它包含了神经网络的权重和偏置项。下面是神经网络中常见的参数矩阵&#xff1a; 权重矩阵&#xff08;Weight Matrix&#xff09;&#xff1a;权重矩阵用于线性变换操作&#xff0c;将输…...

4、Kubernetes 集群 YAML 文件详解

目录 一、YAML 概述 二、YAML 基本语法 三、YAML 数据结构 四、k8s资源清单描述方法 五、YAML 快速编写 1、使用 kubectl create 命令 2、使用 kubectl get 命令导出 yaml 文件 一、YAML 概述 k8s 集群中对资源管理和资源对象编排部署都可以通过声明YAML文件来解决&…...

leetcode93. 复原 IP 地址(java)

复原 IP 地址 leetcode93. 复原 IP 地址回溯算法代码演示 回溯算法 leetcode93. 复原 IP 地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2…...

极光Java 版本服务器端实现别名消息推送

文章目录 引言I 概述1.1 依赖包1.2 极光证书环境参数1.3 构建推送对象II 推送内容2.1 配置推送内容2.2 获取通知消息内容2.3 配置IOS通知内容2.4 配置Android通知内容2.5 发起推送2.6 分批推送2.7 初始化密钥2.8 配置密钥引言 REST API 文档:https://docs.jiguang.cn/jpush/se…...

【Lua学习笔记】Lua进阶——Table(4)继承,封装,多态

文章目录 封装继承多态 封装 // 定义基类 Object {}//由于表的特性&#xff0c;该句就相当于定义基类变量 Object.id 1//该句相当于定义方法&#xff0c;Object可以视为定义的对象&#xff0c;Test可以视为方法名 //我们知道Object是一个表&#xff0c;但是抽象地看&#xff…...

安全性证明(四)Practical Identity-Based Encryption Without Random Oracles

...

Linux中常用的指令

ls ls [选项] [目录或文件] 功能&#xff1a;对于目录&#xff0c;列出该目录下所有的子目录和文件&#xff1b;对于文件&#xff0c;列出该文件的文件名和其他属性 常用选项&#xff1a; -a:列出目录下的所有文件&#xff0c;包括以.开头的隐藏文件 -l:列出文件的详细信息。…...

【java】【面对对象高级4】内部类、枚举、泛型

目录 1、内部类 1.1 成员内部类【了解】 1.1.1 定义 1.1.2 扩展变量 1.2 静态内部类【了解】 1.2.1 定义 1.2.2 扩展变量 1.3 局部内部类【了解】 1.4 匿名内部类【重点】 1.4.1 定义 1.4.1.1 常规写法 1.4.1.2 匿名内部类改造 1.4.2 匿名内部类的常见使用场景 1.4.2…...

Python的用处到底是什么?(三)

11. 数据库操作&#xff1a;Python的库&#xff0c;如sqlite3和SQLAlchemy&#xff0c;可以连接和操作各种类型的数据库。 Python提供了一些库和工具&#xff0c;如sqlite3和SQLAlchemy&#xff0c;用于连接和操作各种类型的数据库。以下是关于这两个库的详细解释&#xff1a;…...

【Nodejs】Express基本使用

Express 中文网 基于 Node.js 平台&#xff0c;快速、开放、极简的 web 开发框架。 1.Express的安装方式 Express的安装可直接使用npm包管理器上的项目&#xff0c;在安装npm之前可先安装淘宝镜像&#xff1a; npm install -g cnpm --registryhttps://registry.npmmirror.com/…...

k8s集群安装v1.20.9

参考网上资料并将异常问题解决&#xff0c;经测试可正常安装集群。 1.我的环境准备 本人使用vmware pro 17新建三个centos7虚拟机&#xff0c;每个2cpu&#xff0c;20GB磁盘存储&#xff0c;内存2GB&#xff0c;其中主节点的内存3GB&#xff0c;可使用外网. 2.所有节点安装D…...

Staples Drop Ship EDI 需求分析

Staples 是一家美国零售公司&#xff0c;总部位于马萨诸塞州弗拉明汉&#xff0c;主要提供支持工作和学习的产品和服务。该公司于 1986 年在马萨诸塞州布莱顿开设了第一家门店。到 1996 年&#xff0c;该公司已跻身《财富》世界 500 强&#xff0c;后来又收购了办公用品公司 Qu…...

模型调参及优化

调参 调权重参数&#xff0c;偏置参数 训练数据集用来训练参数w&#xff0c;b 调超参数 验证数据集用来选择超参数学习率lr&#xff0c;隐藏层大小等 如何调参 当泛化误差和训练误差都没有降下去说明欠拟合&#xff1b;当训练误差降下去&#xff0c;但泛化误差出现上升形式&…...

多数据源数据转换和同步的ETL工具推荐

有许多支持多数据源数据转换和同步的ETL工具可供选择。以下是一些常见的ETL工具和它们支持多数据源数据转换和同步的特点&#xff1a; Apache NiFi&#xff1a;Apache NiFi是一个开源的ETL工具&#xff0c;支持多种数据源的连接&#xff0c;包括文件系统、数据库、消息队列、网…...

配置 gitlab https 访问

文章目录 1. 备份2. 生成SSL证书3. 配置文件4. 重启5. 访问 1. 备份 docker exec -ti gitlab-ce gitlab-rake gitlab:backup:create2. 生成SSL证书 yum install openssl openssl-devel -y mkdir /data/gitlab/config/ssl ; cd /data/gitlab/config/ssl### 生成证书 openssl…...

Kepware Modbus驱动简介

1. Modbus驱动能够解决什么问题&#xff1f; 它是Modbus设备驱动的集合&#xff0c;为用户提供一种方便快捷的Modbus设备数采解决方案。 只需要通过简单的配置就可以将常见的例如Modbus TCP/IP Ethernet、RTU Serial 和 ASCII Serial等协议设备无缝连接到 HMI/SCADA、MES/His…...

从零开始学习CTF——CTF是什么

引言&#xff1a; 从2019年10月开始接触CTF&#xff0c;学习了sql注入、文件包含等web知识点&#xff0c;但都是只知道知识点却实用不上&#xff0c;后来在刷CTF题才发现知识点的使用方法&#xff0c;知道在哪里使用&#xff0c;哪里容易出漏洞&#xff0c;可是在挖src漏洞中还…...

为Android构建现代应用——主体结构

创建Screents和ViewModels 在前面的章节中&#xff0c;我们已经分析了OrderNow项目的理论概念和我们将赋予的组织。 在本章中&#xff0c;我们将开始实现初始结构和模板&#xff0c;这将联接每一个应用程序的部分。 首先将添加以下带有各自视图模型的主屏幕&#xff1a; •…...

【shell脚本】shell脚本之日志切割(进阶实战三)

恭喜你&#xff0c;找到宝藏博主了&#xff0c;这里会分享shell的学习整过程。 shell 对于运维来说是必备技能之一&#xff0c;它可以提高很多运维重复工作&#xff0c;提高效率。 shell的专栏&#xff0c;我会详细地讲解shell的基础和使用&#xff0c;以及一些比较常用的she…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...