阅读源码的目的
我们在开发过程中往往会运用一些市场上一些主流的框架,例如spring,hibernate ,strust 和mybaities 等。
我们往往可能有时候只知道运用,却不知道这些框架内部实现机制。这样我们就需要读这些框架的源码,方便我们更深入的去了解
和熟练的使用这些框架。这里我将介绍下IntelliJ IDEA 开发环境下如何导入源码工程,以及拿到源码如何解读。以spring为例
阅读spring 源码工具
- Spring源码版本:spring-framework-4.3.8
- Gradle版本:gradle-4.4.1
- IDEA版本:13.1
- Java版本:jdk1.8
安装gradle
根据对应版本选择“Download: binary-only”下载地址:https://gradle.org/releases
把gradle.bin.zip解压到任意目录下,如D:\tools\gradle-4.4.1
配置环境变量 (方法和配置JDK环境变量一样步骤)
变量:GRADLE_HOME=D:\tools\gradle-4.4.1
变量:Path ,值: %GRADLE_HOME%\bin;
源码下载
Spring的源码可以从GitHub上下载:https://github.com/spring-projects/spring-framework
-使用命令如下:
- git clone https://github.com/spring-projects/spring-framework.git
- git checkout -b 版本号
源码编译和调试
准备好配置环境,如JDK1.8 ,为防止内存溢出,可以在源码目录的gradlew.bat文件中,修改
-XX:MaxMetaspaceSize=1024m -Xmx1024m -XX:MaxHeapSize=256m 等配置使用IDEA,则参照import-into-idea.md的说明(如果使用Eclipse作为IDE的开发工具,那直接运行./import-into-eclipse.sh 或者 ./import-into-eclipse.bat ,就可以把源码导入到Eclipse中)
- 进入spring-framework 根目录,执行 gradlew :spring-oxm:compileTestJava 对 Spring-oxm 模块进行预编译。
- 源码导入IDEA
编译通过后,就可以把源码导入到 IDEA中了
在IDEA中 File -> New -> Project from Existing Sources -> Navigate to directory ,选择Spring源码目录,导入,然后IDEA会自动的使用Gradle进行构建。构建完成之后,需要做如下设置: - 排除 spring-aspects 项目,这个是Spring 的AOP体系集成了 aspects ,但在IDEA中无法编译通过
排除一些非必要的模块,如spring-jdbc,sping-jmx,spring-webflux等,关注重点的IOC和AOP模块
编写测试Demo
可以创建一个简单的Demo,该Demo依赖于Spring的源码,这样,就可以从外部,运行Demo,跟踪到Spring的内部源码了。为不失一般性,这里的Demo采用maven进行构建,相关的Spring的源码依赖需要在IDEA中设置成本地源码
demo的相关配置
在IDEA设置Spring的项目依赖(设置Spring-core、Spring-beans、Spring-context、Spring-expression,Spring-aop,Spring-jcl 这几个module就可以了);
编写spring配置和用例
service 接口
public interface UserService { String getUser(); }
service 实现类
public class UserServiceImpl implements UserService { public String getUser() { return "USER"; } }
- 配置spring.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-lazy-init="true"> <description>Loan Web Configuration</description> <bean class="com.greekw.spring.UserServiceImpl"></bean> </beans>
- 编写测试demo
public static void main(String[] args) { ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("spring.xml"); context.start(); UserService userService=context.getBean(UserService.class); System.out.println(userService); }
然后就可以 进行Debug了,并且可以Debug到Spring源码内部
问题和解决方案
- Q1:idea 导入 Could not find method jcenter() for arguments [] on object of
在 settings.gradle 配置jcenter
pluginManagement {
repositories {
jcenter()
gradlePluginPortal()
}
}
- Q2:org.gradle.api.internal.MissingMethodException: Could not find method pluginManagement() for arguments
更换gradle的版本到4.x