Spring Cloud OpenFeign源码FeignClientFactoryBean原理
Spring Cloud OpenFeign的FeignClientFactoryBean在实例化过程中,通过FactoryBean接口实现,源码GetObject方法的构建关键步骤包括获取FeignContext、配置Feign.Builder、最新创建HardCodedTarget和调用loadBalance方法。源码这些步骤涉及自动配置、构建FeignClientSpecification的最新使用、Logger和Builder组件的源码定制以及动态代理的生成。最后,构建getObject方法返回的最新是一个接口的代理类,用于执行远程调用。
详细分析:
FeignClientFactoryBean在Spring容器中,通过getObject方法转化为实际的FeignClient实例。首先,它从FeignContext获取相关配置,这个配置在引入OpenFeign依赖时自动注入。接下来,通过getTarget方法,FeignClientFactoryBean配置了Builder组件,如Logger(非Slf4j)、RequestInterceptor、Encoder和Decoder等,同时考虑了用户自定义组件的配置。之后,创建了HardCodedTarget,基于FeignClient接口、注解值和完整URL构建,然后通过loadBalance方法,整合了LoadBalancerFeignClient和HystrixTargeter,进行负载均衡和目标URL定位。
在newInstance方法中,解析了接口方法的注解,生成了MethodHandler,并用FeignInvocationHandler封装,这个InvocationHandler在代理类实例化时被调用,实现了远程调用。最终,通过Proxy.newProxyInstance动态生成了代理类,完成FeignClientFactoryBean的实例化过程。
总的来说,FeignClientFactoryBean实例化是通过一系列配置和代理生成,实现了Spring Cloud OpenFeign的远程调用功能。如果你对源码的深入理解感兴趣,下期文章将继续解析调用源码细节。星运源码网
6. Spring源码篇之FactoryBean
FactoryBean是Spring提供的一个功能强大的小型工厂,用于灵活创建所需Bean。在框架与Spring整合时,尤其是Mybatis-plus中,通过注解可以自动生成Spring Bean,而FactoryBean的功能正是实现批量动态生成Bean。下面详细介绍FactoryBean的源码解析。
首先,我们来看看如何判断一个对象是否为FactoryBean。在Spring的实例化过程中,如果类实现了FactoryBean接口,则会被识别为FactoryBean。而获取FactoryBean时,通常在Bean名称前加上"&"符号。
接下来,我们深入分析FactoryBean的接口。
FactoryBean接口定义了如何创建Bean,包含两个主要方法:getObject和isInstance。getObject用于返回创建的Bean实例,isInstance用于判断一个对象是否由FactoryBean创建。
SmartFactoryBean是FactoryBean的子接口,它提供了额外的特性,允许决定是否提前实例化对象。
在实际使用中,FactoryBean的实例化过程较为关键。如果不希望立即实例化某个非懒加载单例Bean,则需要确保它未被识别为FactoryBean。例如,UserBean的实例化代码在正常情况下不会打印任何输出,表明并未实例化。而通过将UserBean实现为SmartFactoryBean,并使isEagerInit返回true,就能在控制台中观察到UserBean的实例化过程。
获取FactoryBean创建的Bean有多种方式。通过在Bean名称前加"&",可以获取到由getObject方法生成的Bean。此外,若需要获取FactoryBean本身,则可以使用多个"&"符号,Spring会循环遍历,直至获取到实际的Bean。
在Spring实例化完成后,通常会调用getObjectForBeanInstance方法来获取真正的Bean实例。这一过程包括了共享实例(sharedInstance)的引用和Bean名称的处理。最终,通过调用getObject方法,我们能够获取到由FactoryBean生成的实际Bean。
以Mybatis-plus中的代码生成源码MapperFactoryBean为例,说明了如何在实际项目中应用FactoryBean。MapperFactoryBean是Mybatis-plus提供的一个FactoryBean,用于自动注册Mapper接口为Spring Bean。
总结而言,FactoryBean在Spring中扮演着灵活创建和管理Bean的重要角色,尤其在需要动态生成或自定义Bean创建逻辑的场景中。通过理解其源码和使用方法,开发者可以更高效地整合各类框架与Spring,实现更为灵活和高效的系统构建。
Spring Cloud 正式发布!我的天,OpenFeign 要退出历史舞台了?!
大家好,我是栈长。
今天给大家通报一则框架更新消息,时隔 .x 版本发布一年,Spring Cloud .0.0 最新版发布了,来看下最新的 Spring Cloud 版本情况:
Spring Cloud 无疑是现在 Java 微服务事实上的标准,完全基于 Spring Boot 构建,依赖 Spring 生态体系,可以很好的与各种 Spring 生态项目无缝对接。
Maven 依赖先给大家奉上:
Spring Cloud 依赖管理采用的是 import 导入方式,里面管理了许多依赖,统一引入管理,使用时只需要引入对应依赖的坐标即可,不需要指定版本号。
Spring Cloud 目前维护着 4 条版本主线:
关于这些版本线的命名是不是很奇怪?
另外,还有几天都要 年了,怎么现在才发布 版本?
其实 Spring Cloud 最新的版本命名方式早已经变更了,以后就是YEAR.x 这种命名方式了,不清楚的可以看下栈长之前写的两篇文章:
所以说,Spring Cloud .0.0 中的 是指 Spring Cloud .x 版本线,.0.0 则是指 这个版本线的第 1 个版本,而不是指某个年份发布的版本。
新特性解读
Spring Cloud .0.0 是一个大版本,更新了太多内容,栈长不打算全部解读,说几个有意思的更新吧。
完整特性更新参考官方发布文档:
1、系统环境
Spring Cloud .0.0 基于以下环境进行构建:
所以,这也是 Spring Cloud .0.0 的最低依赖要求,升级请小心。
2、模块升级
3、Eureka 已经更新到 Eureka 2.0.0
大家都知道 Eureka 2.x 早已经停止维护了,如该分支最新公告所示:
github.com/Netflix/eure...
虽然 Eureka 2.0.0 是 Eureka 的一个新分支,但这个分支与 7 年前的 2.x-archive 旧实验分支无关。
创建 Eureka 2.x 新分支的分时雷达源码目的是为了与 JakartaEE 兼容而已,让 Spring Cloud Netflix 可以兼容 Spring Framework 6.0 和 Spring Boot 3.0,仅此而已。
4、Spring Cloud OpenFeign 功能完成公告
由于 Spring 现在提供了自己的 HTTP 接口客户端解决方案,比如在最新的 Spring Boot 3.0 中实现接口调用可以有以下两种解决方案:
所以,从 Spring Cloud .0.0 版本开始,Spring Cloud OpenFeign 模块已经视为功能完成状态了,这意味着 Spring Cloud 团队将不再向该模块添加新功能。
虽然 OpenFeign 不会再添加新功能,但还是会继续修复错误和安全问题,并且也还会考虑和审查来自社区的小规模的 pull requests 请求。
这是不是意味着,在不久的将来,OpenFeign 要退出历史舞台了?
Spring Cloud 支持版本
Spring Cloud 支持的版本情况,以及对应的 Spring Boot 版本如下表所示。
需要注意的是: 正常维护中的版本中有 Spring Cloud + 了,其他的版本已经彻底结束生命周期了,官方不再提供维护支持了,非必要,尽量不要再使用了。
目前最新的 Spring Cloud Alibaba .0.4.0 还是基于 Spring Cloud .0.4.0,尚未同步更新最新的 Spring Cloud .0.0 版本,这个在栈长的微服务课程中也有说明了,两者的版本不一定完全同步,也可能会跳过。
总结
Spring Cloud .0.0 是一个革命性的大版本,依赖的系统环境和模块都有大幅度的更新,特别是 JDK 、Spring 基础框架的最低要求,对于想升级的小伙伴来说无疑是一件难事,国内的应用也都还是以 JDK 8 为主,要迁移到 Spring Cloud 版本恐怕还需要不少的时日。
Spring Boot 理论和实战源码仓库:
github.com/javastacks/s...
你们用的哪个 Spring Cloud 版本呢?欢迎留言分享~
好了,今天的分享就到这里了,后面栈长我会更新更多好玩的 Java 技术文章和最新的技术资讯,关注Java技术栈第一时间推送,不要走开哦。
版权声明: 本文系 "Java技术栈" 原创,原创实属不易,转载、引用本文内容请注明出处,抄袭者一律举报+投诉,并保留追究其法律责任的权利。
原来这么简单Springboot多module项目工程搭建这样做就好了。
本文通过构建一个包含5个子模块的项目,演示SpringBoot在Maven环境下的多模块构建过程。
1、创建副工程
a. 通过Spring Initializr创建
b. 创建后删除不需要的长沙弟弟源码文件,保留:.idea文件夹、项目pom文件以及一个*.iml文件
删除前->删除后
2、创建子模块
a. 右键点击父工程,选择New -> Module... 创建子模块。依次创建scaffold-common、scaffold-api、scaffold-dao、scaffold-service和scaffold-web共5个模块
注意:除了scaffold-web子模块创建时选择添加Spring Web依赖,其他模块暂时不添加依赖。
b. 将所有子模块的mvnw、mvnw.cmd文件及.mvn文件夹全部删除
c. 对于src里的内容,只保留scaffold-web的启动类和配置文件,其他子模块的启动类和配置文件都删除
3、编辑父工程的pom.xml文件
a. 将父工程pom.xml文件修改成如下内容,声明父工程包含的子模块,同时抽取统一的配置信息和依赖版本控制,方便子pom直接引用,简化子pom的配置
1、多模块项目中,父模块打包类型必须是pom。2、因为开发框架是Spring Boot,父模块默认继承spring-boot-starter-parent,因此可以删除spring-boot-starter和spring-boot-starter-test依赖(祖先已经包含了)
父工程pom.xml如下
4、编辑子模块pom.xml
a. 子模块scaffold-common的pom.xml文件内容如下,其中parent要使用顶层的父模块,同时由于项目用到了Lombok,所以还添加了lombok依赖
由于子模块的配置信息会继承父模块的,所以子模块原来的properties可删掉
b. 子模块scaffold-dao的pom.xml文件内容如下,同样parent要使用顶层的父模块,并添加scaffold-common子模块,以及数据库相关依赖
c. 子模块scaffold-service的pom.xml文件内容如下,同样parent要使用顶层的父模块,并添加scaffold-dao子模块依赖
实际开发中dao模块会引入对数据相关包的依赖,如mysql、Druid连接池、mybatis等
d. 子模块scaffold-web的pom.xml文件内容如下,同样parent要使用顶层的父模块,并添加scaffold-service子模块依赖
注意:之前创建这个子模块的时候已经添加了spring-boot-starter-web依赖,如果没有则手动添加
e. 子模块scaffold-api的pom.xml文件内容如下,同样parent要使用顶层的父模块
5、移动项目启动类所在包
a. 目前项目启动类ScaffoldWebApplication在com.xyy.scaffold包下面,需要将其移动到com.xyy包下
b. 移动的方式是右键点击ScaffoldWebApplication选择Refactor -> Move,将to package改成com.xyy
c. 移动后
6、编写controller并启动
a. 在com.xyy.scaffoldweb下写个测试Controller
b. 启动项目
c. 打开浏览器访问
搭建项目工程结构
搭建好多module项目并成功启动后,再来构建项目工程结构
1、scaffold-web模块
主要包含一个启动类、一个web和一个config包
2、scaffold-service模块
主要包含业务逻辑代码,包含业务接口及其实现类
3、scaffold-dao模块
主要包含数据访问层内容,DO定义、DB访问层以及数据库相关配置类
4、scaffold-common模块
包含每个模块可能都会用的一些基础类,如:dto、错误码、util工具类以及全局异常类和常量等
5、scaffold-api模块
主要负责外部依赖服务的管理,包含外部依赖服务的定义以及访问部分,以及通过facade模式做的封装类,如:request、response定义;外部服务api接口和外部服务通用枚举等
6、整体服务的调用过程如下
整理不易,干货分享就找@搬砖后端研发
本文中涉及的源码,如有需要可以私聊我呀
Spring源码 1.源码的下载与编译(by Gradle)
为了获得Spring源码并成功编译,我们首先需要下载源码。方法之一是使用Git clone命令,前提是我们已安装Git。但要注意,最新版本可能需要JDK ,若需使用JDK 8,推荐选择较旧版本。GitHub上,最新稳定版本为5.2..RELEASE,这是一个GA(General Availability)版本,表示正式发布的版本,适合在生产环境中使用。如果你使用的是JDK 8,建议选择分支版本。
如果GitHub服务不可用或下载速度缓慢,可以考虑从其他资源库下载。例如,可以使用csdn提供的资源链接支持作者,或者直接从gitee下载源码。
下载源码后,导入IDEA并选择Gradle工程。IDEA会自动加载,但可能遇到一些报错。如果报错提示“POM relocation to an other version number is not fully supported in Gradle”,需要将xml-apis的版本号更改为1.0.b2。这可以通过在项目的build.gradle文件中添加指定版本的代码来实现。
加载并配置新模块后,可以通过新建测试类来进行验证。在build.gradle中添加配置,并在模块中新建文件,包括一个启动类、一个配置类和一个实体类。记得刷新Gradle,进行测试。
测试结果应显示新建的实体类已被Spring容器加载。如果在测试中遇到问题,可以通过检查编译工具、编译器和项目结构来解决。确保使用本地Gradle路径、选择JDK 1.8版本,并在项目设置中选择正确的JDK版本。
读spring源码,为什么要用gradle构建。直接导入idea不行吗?
在Spring源码开发中,选择使用Gradle构建项目是出于提高构建效率的目的。相较于Maven,Gradle能显著缩短项目构建所需时间,为开发者节省大量等待时间,从而更高效地完成代码修改与功能实现。
下载Gradle的具体版本至关重要,需根据Spring源码的版本确定,通过GitHub查找对应版本。例如,若Spring源码版本需配合JMH-gradle-plugin的0.6.6版本,则Gradle版本应为6.8及以上,确保插件与Gradle版本兼容,避免构建过程中出现错误。不兼容可能导致“Only Project build scripts can contain plugins { } blocks”等异常。
面对新版本Spring源码的编译需求,建议更新至JDK,但若偏好使用JDK8,可继续参考后续内容。通常,JDK8建议与5.0-5.6.4版本的Gradle配合使用,以减少因版本不兼容导致的问题,提高学习与开发效率。
正确安装Gradle,首先从下载地址获取安装包,双击解压后,需在`.bash_profile`文件中添加环境变量。在命令行输入`gradle`测试安装,如出现错误则需执行`java -version`确认JDK版本,并通过`source ~/.bash_profile`刷新环境变量,重新尝试安装。
配置IDEA构建时,选择本地Gradle路径、指定本地Gradle安装位置及本地JDK版本,确保项目构建顺利进行。
最后,检查编译结果,无错误即表示编译成功。如编译速度慢,可考虑修改镜像配置,通过在`settings.gradle`文件中添加阿里云镜像仓库及在`build.gradle`文件中进行相关设置,优化构建过程,提高效率。
Spring 源码学习 :initMessageSource
前言
阅读完registerBeanPostProcessors源码后,接下来就是initMessageSource这一步骤,其主要功能是初始化国际化文件。
按照惯例,首先通过官网了解国际化的用法,然后深入研究源码。
官网1..1. Internationalization using MessageSource[1]中提到,MessageSource的主要作用是使用国际化,定制不同的消息。
需要注意的是,MessageSource定义的Bean名称必须为messageSource,如果找不到则会默认注册DelegatingMessageSource作为messageSource的Bean。
1. 创建国际化文件
2. 声明MessageSource
在JavaConfig中声明MessageSource,记得名字一定要叫做messageSource!
3. 测试结果
执行后输出结果如下:
了解了国际化是如何使用的之后,再看看这一步的源码,就知道其作用了!
initMessageSource源码
这块源码唯一值得关注的地方就是,Bean的名称必须要是messageSource。
总结
本文通过官网,了解到什么是国际化,以及国际化的使用,并结合代码和源码,知其然,知其所以然。
当然本文需要注意的地方就是国际化MessageSource的Bean名称要必须为messageSource。
搭建springcloud架构(springcloud完整架构流程图)
微服务架构下的Spring Cloud项目搭建(一、框架简介)旨在为希望学习搭建Spring Cloud项目的开发者提供一个从零开始的详细教程。欢迎各位技术同仁参与讨论,互助学习,共同进步。项目源码存放于Gitee,具体链接请参考文末。使用IntelliJ IDEA从零开始搭建Spring Cloud微服务项目。以下内容基于一个微服务新手的实践经验,仅供参考。
1. 启动Spring Cloud Eureka注册中心
所有服务都将作为Eureka客户端注册到该中心,并通过服务名实现服务间的相互调用。
2. Spring Cloud Config提供统一配置
其他服务可以读取这些配置信息。
3. 提供者服务(Provider)
生产者服务不直接暴露给外部,仅供消费者服务调用。
4. Spring Cloud Gateway作为统一入口
用户通过该网关访问消费者服务。
接下来,在空Maven项目中创建新的模块,可以选择使用Spring Initializr快速生成Spring Cloud模块,或者继续创建空模块。
- `common`模块:存放公共库,如DAO、模型、工具类等。
- `config-dev`模块:存储开发环境配置文件,提交到git后,Spring Cloud Config会从中读取配置。
大部分服务(非独立应用如Spring Cloud Config、Spring Cloud Gateway等)需要添加`spring-boot-starter-web`依赖以构建Web应用。
以下是在IntelliJ IDEA中使用Spring Initializr构建新模块的步骤。
在配置文件中,`bootstrap.yml`具有较高优先级,会首先加载且不会被`application.yml`覆盖。因此,相关的Spring Cloud配置需在`bootstrap.yml`中设置。
在Spring Cloud Gateway的配置中,展示了如何从配置仓库`config-dev`中读取配置文件。`spring.cloud.config`和`eureka.client`的配置已经在`bootstrap.yml`中设置,故不再详述。
在多模块项目中,为了扫描其他模块的MyBatis文件,需要进行额外的配置。
消费者服务可以通过Feign进行声明式服务调用。
Spring Cloud微服务架构能够将服务解耦,独立部署,结合devops实践能充分发挥其优势。GitLab提供了内置的devops功能,通过在项目中添加`.gitlab-ci.yml`文件,推送至GitLab后可自动执行预设命令。接下来,简要介绍GitLab的安装部署。
在CentOS 7中,默认的Git版本为1.8.3.1,需要更新至最新版本,否则在执行自动构建时会出现错误。更新步骤请参考GitLab官方文档。
GitLab和GitLab Runner的安装配置请参考官方文档。
在配置文件`/etc/gitlab/gitlab.rb`中进行必要的配置。
下面通过一系列步骤快速搭建一个简单的Spring Cloud微服务工程。首先,父工程继承`spring-boot-starter-parent`,以便子工程能够作为Spring Boot项目自动创建,并统一Spring Cloud的依赖版本为`Finchley.RELEASE`。
选择Eureka作为注册中心,创建一个新的子工程并指定父工程。导入Eureka服务端启动器和Web支持。
订单服务作为一个Eureka客户端,同样指定父工程并导入相关依赖。
用户服务同样作为Eureka客户端,导入依赖并启动。
在IDE中配置好相关依赖和启动器后,启动Eureka服务端工程,随后启动订单服务和用户服务,验证服务是否成功注册至Eureka。
接下来,在订单服务中作为服务提供者,允许用户服务调用订单信息。
使用浏览器调用用户服务的接口,验证订单服务是否成功被调用。
最后,列出开发工具和使用的版本信息,确保Spring Boot和Spring Cloud版本对应。
本文档主要作为Spring Cloud微服务入门搭建及服务调用的教程,开发工具为IntelliJ IDEA .2.3,Java版本为1.8,Maven版本为3.3.9,Spring Boot为2.1.3.RELEASE,Spring Cloud为Greenwich.SR5。
IDE配置不再详述,之后直接配置`pom.xml`。对于独立的服务项目,可以选择继承父项目或独立配置依赖。在`pom.xml`中,指定Spring Boot和Spring Cloud版本。
在控制器中调用其他服务接口,可以使用RestTemplate实现,并配置相应的RestTemplate配置文件。
在用户服务启动类中,通过RestTemplate调用订单服务接口。
在浏览器中访问相应的接口,验证服务之间的调用是否成功。
2024-11-30 00:27
2024-11-29 23:13
2024-11-29 22:55
2024-11-29 22:34
2024-11-29 22:13