学习源码的第八个月,我成了Spring的开源贡献者

简介:

学习源码的第八个月,我成了Spring的开源贡献者

目录

我的经历
碰到的问题
1、担心闹乌龙
2、不知道要怎么提交
3、英文
4、担心问题描述的不清楚
给你的建议
@

目录
我的经历
碰到的问题
1、担心闹乌龙
2、不知道要怎么提交
3、英文
4、担心问题描述的不清楚
给你的建议
我的经历
关注我的朋友都知道,关注两个字划重点,要考!

我最近一直在写Spring的文章,而且仅仅是Spring FrameWork的文章 ,从最开始的官网入门到现在源码的深度分析。主要就是三个系列

官网入门系列,Spring官网读书笔记,这一系列的文章是入门Spring的不二之选,也是后续源码阅读的基础

杂谈系列,Spring杂谈,这主要是一些补充内容,可以帮助大家更全面学习到Spring中的各个知识点,同时也会分享一些源码阅读技巧,个人学习心得之类的,杂谈嘛,就是不知道放哪里的文章都打算放这里,比如这篇文章。

源码分析系列,Spring源码解析,该专栏目前正在创作中,相对而言学习难度比较大,而且因为笔者写的比较细,估计大部分同学看起来会很费劲,不过如果你能认真看完,收获绝对巨大!当然有不懂得地方也可以给笔者留言,或者关注文章末尾的公众号。

本文的主要目的是教(zhuang)学(bi)

就是从笔者的实际经验出发,谈一谈怎么成为一个开源项目的贡献者。

我先说说我自己的经历吧,在创作上篇文章的时候,笔者发现Spring在实例化对象的时候有这么一段代码,在org.springframework.beans.factory.support.ConstructorResolver#resolveConstructorArguments方法中

// 本文不探讨技术细节,只是为了简单说明这个问题,所以省略无关代码
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,

        ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

  // ....
    for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
        int index = entry.getKey();
        if (index < 0) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Invalid constructor argument index: " + index);
        }
        // 问题就出在这里
        if (index > minNrOfArgs) {
            minNrOfArgs = index + 1;
        }
   // ..... 

上述代码中,minNrOfArgs这个变量就是保存方法需要的最小参数个数,但是index是下标索引,索引是从0开始的,如果有下标为n的元素,那么最小的参数个数应该是n+1嘛,所以if中的逻辑是没有问题的,但是if这个判断是有问题的,正确的做法应该是

if (index+1 > minNrOfArgs) {

minNrOfArgs = index + 1;

}
当发现这个问题的时候,第一反应就是肯定是我的姿势不对,错的怎么可能是代码,肯定是我!

接下来,我就对这段代码进行了惨无人道的调试,在无数次debug后,我发现,这个地方确实有问题!

在确认了这个问题之后,我要思考的就是怎么把自己的想法反馈给Spring,换而言之,怎么为伟大的开源来做贡献呢?正常来要达到这个目的有两个方式

提交issue
直接在GitHub上提交PR(pull request)
对应的就是在GitHub上点击下图红框选中的两个位置

如果是使用提交issue的方式,相当于给官方团队提交了一个议题,这个议题可能是你发现代码中的某个bug,也可能是你觉得官方的做法不够好,你有更好的想法等等。感兴趣的话,大家可以去看看Spring中现在有哪些还未关闭的issue,说不定其中一个你就能解决呢~!

如果要采用提交PR的方式的话,首先你得将代码fork到自己的GitHub中,然后在从自己的GitHub检出到本地,在本地做完修改后,提交到GitHub仓库中,最后从自己的GitHub向Spring官方仓库发起一个PR。

像我的话很早就已经将代码fork到了自己GitHub

上图中的第一个红框,说明我这个仓库是从Spring官方fork过来的,第二个红框就是可以从这里向Spring官方提交一个PR。关于详细的如何提交PR,大家可以自行百度,这里不做详细的介绍了。

另外,说了这么多,先给大家看下我提交的issue吧。

issue链接:https://github.com/spring-projects/spring-framework/issues/25130

因为内容也不长,所以我这里把原文就直接放到下面了

In ConstructorResolver:

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,

        ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
    TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
    // ...

    for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
        int index = entry.getKey();
        if (index < 0) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Invalid constructor argument index: " + index);
        }
        if (index > minNrOfArgs) {
            minNrOfArgs = index + 1;
        }
        // ....
    }

// ....
return minNrOfArgs;
}
I assume that method resolveConstructorArguments is to resolve contructor arguments in the XML file and return the minimum number of parameters required by contructor 。but if the first parameter is autowired , the second parameter is config by XML file,the method will not work well。

example:

public class FactoryObject {

public DmzService getDmz(String name, int age, Date birthDay, OrderService orderService) {

public DmzService getDmz(OrderService orderService,String name) {
    
    return new DmzService(orderService,name);
}

}
<?xml version="1.0" encoding="UTF-8"?>

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
   default-autowire="constructor">
<bean id="factoryObject" class="com.dmz.spring.first.instantiation.service.FactoryObject"/>

<bean class="com.dmz.spring.first.instantiation.service.OrderService" id="orderService"/>

<bean id="dmzService" factory-bean="factoryObject" factory-method="getDmz">
    <constructor-arg index="1"  value="dmz"/>
</bean>


the resolveConstructorArguments method will return 1,but correct answer is 2。

I think the problem arises because of this judgment:

if (index > minNrOfArgs) {
minNrOfArgs = index + 1;
}
It might be better to change it to look like this

if (index + 1 > minNrOfArgs) {
minNrOfArgs = index + 1;
}s
我在提交issue时主要是按照这种思路

首先摆出有问题的代码
描述具体的问题,我是直接通过一个例子来描述的
说出自己的建议
这几天我又多看了看别人提交的issue,对比起来,我觉得至少应该还要添加一点

应该要明确的指出具体哪个版本上出现的问题
碰到的问题
1、担心闹乌龙
虽然在之前我已经调试过了无数次代码,但是心里还是没谱啊。毕竟我这么谨(cai)慎(ji)的一个人,万一被人喷了怎么办?不知道你会不会这么想,反正我当时就是这么想的,如果你是这么想的,建议你去看看别人提交的issue。搜索条件如下

is:closed label:"status: invalid"

我觉得你看几个,自然就有信心了!

2、不知道要怎么提交
每个开源的项目,只要作者希望这个项目越来越好的话,都会详细的说明如何给这个项目做开源贡献,Spring肯定也不例外,这里还是以提交issue为例,当你点击New issue的时候会出现下面这张图

在上图左边的框里很明确的告诉了你提交issue应该要注意什么

首先,你应该要去Stack Overflow提问
如果是bug,你应该要指明版本以及你想要做什么
如果是一个增强的话,要提供上下文并且描述清楚问题
同一个问题,issue跟PR最好只提交一个,因为GitHub认为它们是一样的,如果你还不能确定的话,先提交一个issue
而右上角还有更加详细的文档可供参考。

3、英文
大家应该看到了,整个issue都是用英文写的,那么英文不好怎么办呢?这个时候就要掏出我们的神器了

嗯,就是词典,笔者习惯是使用有道词典。我建议英文不好的同学可以这样,先将整个issue用中文写好,如果你真的英文一窍不通的话,可以直接通过翻译软件逐句翻译,然后粘贴到GitHub上。但是千万千万不要使用中文,就像下面这个哥们

issue链接:https://github.com/spring-projects/spring-framework/pull/25127

像这种issue是会被直接打上invalid(不合格)标签的,你就想想吧,你学不会英文,你指望我们的外国朋友能看懂中文嘛?是我中华上线五千年的文化不够博大精深吗?

4、担心问题描述的不清楚
其实这个问题就是因为英文不好衍生出来的。因为英文不好,自然就会担心我写的东西他能不能看懂呢?我的建议就是,结合你测试的代码去描述问题。你不用去担心别人看不懂你写的代码,就以我那个issue的处理流程为例吧。

在你刚刚提交issue时,有专门的issuemaster(issue管理员)会给你提交的issue打上一个wait-for-triage的标签,标志这个issue是待处理的。

随后我提交的这个issue,就被指派给了jhoeller。你要担心他看不懂代码吗?给你看两个东西吧

你知道那个红框是啥意思吗?就是说我发现的那个有问题代码的类的作者就是他。

再看一张

就是说,jhoeller从2003年开始就已经是Spring这个项目的管理者以及发布经理了。2003年,我还是一个小学生........

所以啊,只要你稍微正常点,基本上人家都能get到你的点。

给你的建议
其实笔者从发现这个问题到最终提交issue大概经过了一周时间,期间一直在犹豫要不要提交issue,就是因为上面提到的几个问题,一直踌躇不前。但是等我下定决心要去做这件事的时候总共就花了几个小时的时间。包括研究issue提交的规则以及写一篇英文版的issue。并且我提交issue的第二天就马上被处理了,并且jhoeller在 f9aae8d 这个commit中已经接受我的建议。

所以我要说的就是,

真正动手的话,不管什么问题总能找到解决方案

而只是停留在空想,在踌躇,你永远有一堆问题

临渊羡鱼,不如退而结网

以此文与君共勉!

如果本文对你由帮助的话,记得点个赞吧!也欢迎关注我的公众号,微信搜索:程序员DMZ,或者扫描下方二维码,跟着我一起认认真真学Java,踏踏实实做一个coder。

原文地址https://www.cnblogs.com/daimzh/p/13034515.html

相关文章
|
6月前
|
监控 Java 应用服务中间件
微服务——SpringBoot使用归纳——为什么学习Spring Boot
本文主要探讨为什么学习Spring Boot。从Spring官方定位来看,Spring Boot旨在快速启动和运行项目,简化配置与编码。其优点包括:1) 良好的基因,继承了Spring框架的优点;2) 简化编码,通过starter依赖减少手动配置;3) 简化配置,采用Java Config方式替代繁琐的XML配置;4) 简化部署,内嵌Tomcat支持一键式启动;5) 简化监控,提供运行期性能参数获取功能。此外,从未来发展趋势看,微服务架构逐渐成为主流,而Spring Boot作为官方推荐技术,与Spring Cloud配合使用,将成为未来发展的重要方向。
193 0
微服务——SpringBoot使用归纳——为什么学习Spring Boot
|
29天前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
5月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
375 70
|
5月前
|
人工智能 Java 决策智能
Java版Manus实现来了,Spring AI Alibaba发布开源OpenManus实现
此次官方发布的 Spring AI Alibaba OpenManus 实现,包含完整的多智能体任务规划、思考与执行流程,可以让开发者体验 Java 版本的多智能体效果。它能够根据用户的问题进行分析,操作浏览器,执行代码等来完成复杂任务等。
1324 57
|
5月前
|
Java Spring
Spring框架的学习与应用
总的来说,Spring框架是Java开发中的一把强大的工具。通过理解其核心概念,通过实践来学习和掌握,你可以充分利用Spring框架的强大功能,提高你的开发效率和代码质量。
143 20
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
114 0
|
8月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
300 7
|
自然语言处理 Java Spring
怒肝8个月源码,我成为了 Spring 开源贡献者(续)
我最近一直在写Spring的文章,而且仅仅是Spring FrameWork的文章 ,从最开始的官网入门到现在源码的深度分析。
怒肝8个月源码,我成为了 Spring 开源贡献者(续)
|
2月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
725 0