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

@javascript

个人经历

关注个人朋友都知道,关注两个字划重点,要考!html

img

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

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

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

img

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

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

image-20200602071958918

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

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

// 本文不探讨技术细节,只是为了简单说明这个问题,因此省略无关代码	
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后,我发现,这个地方确实有问题!

image-20200602203349414

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

  • 提交issue
  • 直接在GitHub上提交PR(pull request)

对应的就是在GitHub上点击下图红框选中的两个位置

image-20200602204827377

若是是使用提交issue的方式,至关于给官方团队提交了一个议题,这个议题多是你发现代码中的某个bug,也多是你以为官方的作法不够好,你有更好的想法等等。感兴趣的话,你们能够去看看Spring中如今有哪些还未关闭的issue,说不定其中一个你就能解决呢~!

若是要采用提交PR的方式的话,首先你得将代码fork到本身的GitHub中,而后在从本身的GitHub检出到本地,在本地作完修改后,提交到GitHub仓库中,最后从本身的GitHub向Spring官方仓库发起一个PR。

像个人话很早就已经将代码fork到了本身GitHub

image-20200602211528302

上图中的第一个红框,说明我这个仓库是从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"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   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>

</beans>

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时主要是按照这种思路

  1. 首先摆出有问题的代码
  2. 描述具体的问题,我是直接经过一个例子来描述的
  3. 说出本身的建议

这几天我又多看了看别人提交的issue,对比起来,我以为至少应该还要添加一点

  • 应该要明确的指出具体哪一个版本上出现的问题

碰到的问题

一、担忧闹乌龙

虽然在以前我已经调试过了无数次代码,可是内心仍是没谱啊。毕竟我这么谨(cai)慎(ji)的一我的,万一被人喷了怎么办?不知道你会不会这么想,反正我当时就是这么想的,若是你是这么想的,建议你去看看别人提交的issue。搜索条件以下

image-20200602221719579

is:closed label:"status: invalid"

我以为你看几个,天然就有信心了!

二、不知道要怎么提交

每一个开源的项目,只要做者但愿这个项目愈来愈好的话,都会详细的说明如何给这个项目作开源贡献,Spring确定也不例外,这里仍是以提交issue为例,当你点击New issue的时候会出现下面这张图

image-20200602222421975

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

  • 首先,你应该要去Stack Overflow提问
  • 若是是bug,你应该要指明版本以及你想要作什么
  • 若是是一个加强的话,要提供上下文而且描述清楚问题
  • 同一个问题,issue跟PR最好只提交一个,由于GitHub认为它们是同样的,若是你还不能肯定的话,先提交一个issue

而右上角还有更加详细的文档可供参考。

三、英文

你们应该看到了,整个issue都是用英文写的,那么英文很差怎么办呢?这个时候就要掏出咱们的神器了

image-20200602214339837

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

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

image-20200602215146927

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

四、担忧问题描述的不清楚

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

image-20200602215944850

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

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

image-20200602220527438

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

再看一张

image-20200602220833491

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

菜

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

给你的建议

其实笔者从发现这个问题到最终提交issue大概通过了一周时间,期间一直在犹豫要不要提交issue,就是由于上面提到的几个问题,一直踌躇不前。可是等我下定决心要去作这件事的时候总共就花了几个小时的时间。包括研究issue提交的规则以及写一篇英文版的issue。而且我提交issue的次日就立刻被处理了,而且jhoellerf9aae8d 这个commit中已经接受个人建议。

因此我要说的就是,

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

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

临渊羡鱼,不如退而结网

以此文与君共勉!

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

公众号

我叫DMZ,一个在学习路上匍匐前行的小菜鸟!

本文由博客群发一文多发等运营工具平台 OpenWrite 发布

相关文章
相关标签/搜索