通过Spring源码更好的学习spring源码

381 阅读2分钟

1.背景

最近在学习spring的源码,找到了个更好的学习源码的方式,可以在spring的源码上留下自己的注释,特地分享一下
\color{red}{多图预警}

2. 准备工具

编辑器自然是推荐idea了,git也是必不可少的,另外由于spring是基于Gradle做依赖管理的,所以要提前安装好gradle。

3.下载spring

spring涉及的第三方包还挺多的,grandle依赖处理的时候可能比较慢,需要改下gradle的配置
C:\Users\你自己的用户名\.gradle这个目录下,新建一个.init.gradle的文件

allprojects{
    repositories {
        def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'
        all { ArtifactRepository repo ->
            if(repo instanceof MavenArtifactRepository){
                def url = repo.url.toString()
                if (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/')) {
                    project.logger.lifecycle "Repository ${repo.url} replaced by $REPOSITORY_URL."
                    remove repo
                }
            }
        }
        maven {
            url REPOSITORY_URL
        }
    }
}

git地址: github.com/spring-proj…
由于spring-framework的master分支是snapshot版本的,改动比较频繁,建议基于某个release版本学习源码,比如5.2.x这个分支

4. 建立自己的module

在当前项目下新建一个module,比如我们想学习ioc的源码,我们的module的名字可以写成ioc-study, 当然我们的module的依赖管理需要选择gradle

点击finish后,需要等gradle为我们自动生成一些文件夹。

5. gradle引用当前项目下的其他module

这里我们以ioc为案例,介绍下怎么引用当前项目下的module 在ioc-study这个module下,修改build.gradle文件的文件名为ioc-study.gradle(即你建的module的名字),并修改配置如下

plugins {
    id 'java'
}

group 'org.springframework'
version '5.3.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // junit
    testCompile group: 'junit', name: 'junit', version: '4.10'
    // lombok
    compileOnly 'org.projectlombok:lombok:1.18.12'
    //annotationProcessor 'org.projectlombok:lombok:1.18.12'
    testCompileOnly 'org.projectlombok:lombok:1.18.12'
    //testAnnotationProcessor 'org.projectlombok:lombok:1.18.12'
    // 引用对应的module
    compile(project(":spring-beans"))
    compile(project(":spring-context"))
    compile(project(":spring-core"))
}

然后刷新下gradle的引用,就可以使用到对应已经引用到的module的内容了,这样子就可以像本地开发一样,更好的追踪源码了

6. 测试

6.1 新建测试类MyTestBean.java

public class MyTestBean {

	private String testStr = "testStr";

	public String getTestStr() {
    	return testStr;
	}

	public void setTestStr(String testStr) {
		this.testStr = testStr;
	}
}

6.2 spring.xml

resource文件夹下新建spring.xml文件

<?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">
	<bean id="myTestBean" class="cn.ddlover.ioc.bean.MyTestBean"/>
</beans>

6.3 新建测试类BeanFactoryTest.java

public class BeanFactoryTest {

	public static void main(String[] args) {
		DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
		BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
		Resource resource = new ClassPathResource("spring.xml");
		beanDefinitionReader.loadBeanDefinitions(resource);

		MyTestBean myTestBean = (MyTestBean) defaultListableBeanFactory.getBean("myTestBean");
		System.out.println(myTestBean.getTestStr());
	}
}

6.4 启动测试类

如果没有啥大问题的话,控制台应该是能输出testStr
细心的朋友可能会发现,这里没有使用常见的XmlBeanFactory作为bean工厂,这里的其中一个原因是XmlBeanFactory被spring标记为@Deprecated,在gradle环境下,使用被@Deprecated注解标注的类,会因为异常导致编译失败而无法执行。 另外的原因,就等我下次写的时候解释吧~~~