Spring源码深度解析:一、Spring整体架构和源码环境搭建
Spring Core:框架的最基础部分,提供 IoC 容器,对 bean 进行管理。Spring Context:继承BeanFactory,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化等功能。Spring DAO:提供了JDBC的抽象层,还提供了声明性事务管理方法。Spring ORM:提供了JPA、JDO、Hibernate、MyBatis 等ORM映射层.Spring AOP:
一、前言
文章目录:Spring源码深度解析:文章目录
二、Spring整体架构
-
Spring Core
:框架的最基础部分,提供 IoC 容器,对 bean 进行管理。 -
Spring Context
:继承BeanFactory,提供上下文信息,扩展出JNDI、EJB、电子邮件、国际化等功能。 -
Spring DAO
:提供了JDBC的抽象层,还提供了声明性事务管理方法。 -
Spring ORM
:提供了JPA、JDO、Hibernate、MyBatis 等ORM映射层. -
Spring AOP
:集成了所有AOP功能 -
Spring Web
:提供了基础的 Web 开发的上下文信息,现有的Web框架,如JSF、Tapestry、Structs等,提供了集成 -
Spring Web MVC
:提供了 Web 应用的 Model-View-Controller 全功能实现。
三、环境搭建
1、gradle安装与配置
1.1 下载
Gradle
是一个基于JVM
的构建工具,是一款通用灵活的构建工具,支持maven
, Ivy
仓库,支持传递性依赖管理,而不需要远程仓库或者是pom.xml
和ivy.xml
配置文件,基于Groovy
,build
脚本使用Groovy
编写,需要到gradle官网下载对应版本,在Spring
源码项目选择gradle->wrapper->gradle-wrapper.properties可以查看当前版本的spring5.0
源码版本对应的gradle
版本
这里我安装的是gradle4.4.1
下载安装的是bin版,仅包含二进制。如果你使用IDEA的话,它会推荐下载all版,包含源代码,这样IDEA就可以分析源代码,提供更加精确的gradle脚本支持。
1.2、安装条件
gradle
手动安装时,须先安装 jdk 1.8
或以上版本
1.3、安装过程
这里我们下载右边的:
-
解压 gradle-4.4.1-bin.zip
解压
gradle-4.4.1-bin.zip
到任意目录下,例如:D:\gradle\gradle-4.4.1
-
配置环境变量
- 新建环境变量
设置GRADLE_HOME
系统变量为gradle目录D:\gradle\gradle-4.4.1
- 添加到
path
路径中%GRADLE_HOME%\bin
- 新建环境变量
1.4、配置本地仓库与仓库源
GRADLE_USER_HOME
D:\gradle\gradle_repository
# 新建环境变量
变量名:GRADLE_USER_HOME
变量值:自定义Gradle仓库目录或者Maven的仓库目录
配置仓库源
在Gradle安装目录下的 init.d
文件夹下,新建一个 init.gradle
文件,里面填写以下配置:
allprojects {
repositories {
maven { url 'file:///D:/gradle/gradle_repository'}
mavenLocal()
maven { name "Alibaba" ; url "https://maven.aliyun.com/repository/public" }
maven { name "Bstek" ; url "https://nexus.bsdn.org/content/groups/public/" }
mavenCentral()
}
buildscript {
repositories {
maven { name "Alibaba" ; url 'https://maven.aliyun.com/repository/public' }
maven { name "Bstek" ; url 'https://nexus.bsdn.org/content/groups/public/' }
maven { name "M2" ; url 'https://plugins.gradle.org/m2/' }
}
}
}
repositories
中写的是获取jar包的顺序:①本地Maven路径。②mavenLocal()是获取Maven本地仓库的路径,和第一条一样,但是不冲突。③④条就是自己的配置的镜像路径。⑤mavenCentral() 是从Apache提供的中央仓库获取jar包
1.5、测试
gradle -v 显示如下截图:
2、配置到IDEA
在 Gradle home
中选择安装的Gradle
的路径。如果在变量和配置文件中设置了Gradle
的仓库路径,在Service directory path
中就会自动填写地址,如果想改的话可以手动修改。
四、源码
源码链接获取
- 进入官网https://projects.spring.io/spring-framework/,点击那个小猫的图像,进入github下载相应版本的spring源码。
- 切换为最新的 Spring 5.0. x版 源码 ,获取 Git 分支链接
1、源码下载及 IDEA 导入
-
IDEA克隆源码到自定义的目录下:https://github.com/spring-projects/spring-framework.git
也可以手动直接下载源码到本地 -
将jdk版本升级到1.8,因为在最新的Spring中使用到了jdk1.8的新特性,如果不升级到1.8会报错;此处的gradle使用我们之前自己安装的4.4.1版本,不要用IDE自带的;
-
打开项目下build.gradle文件,添加阿里云的仓库
因为spring5.0下载jar包需要用户认证,下载不下来依赖;这里我们选择阿里云的仓库
maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://maven.aliyun.com/repository/spring' } maven { url 'https://maven.aliyun.com/repository/spring-plugin' }
如图所示:
最后idea会自动编译spring源码,编译成功以后,所有的模块都会有个小小的蓝色图标,表示编译成功,至此spring源码导入完成。
重要提醒!重要提醒!重要提醒!
2、在选择Build–>Build Project编译报有几下报错
-
找不到符号: 类 DefaultNamingPolicy,Objenesis,InstantiatorStrategy,ObjectInstantiator 等
具体报错如下:D:\Idea2019\workspace-senior\spring-framework\spring-core\src\main\java\org\springframework\cglib\core\SpringNamingPolicy.java Error:(30, 41) java: 找不到符号 符号: 类 DefaultNamingPolicy Error:(34, 9) java: 方法不会覆盖或实现超类型的方法 D:\Idea2019\workspace-senior\spring-framework\spring-core\src\main\java\org\springframework\objenesis\SpringObjenesis.java Error:(20, 50) java: 程序包org.springframework.objenesis.instantiator不存在 Error:(21, 46) java: 程序包org.springframework.objenesis.strategy不存在 Error:(22, 46) java: 程序包org.springframework.objenesis.strategy不存在 Error:(35, 41) java: 找不到符号 符号: 类 Objenesis Error:(47, 23) java: 找不到符号 符号: 类 InstantiatorStrategy 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(49, 60) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(68, 32) java: 找不到符号 符号: 类 InstantiatorStrategy 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(110, 20) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(122, 23) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(69, 68) java: 找不到符号 符号: 类 StdInstantiatorStrategy 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(111, 17) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(113, 25) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(119, 25) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(125, 25) java: 找不到符号 符号: 类 ObjectInstantiator 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(131, 24) java: 找不到符号 符号: 类 ObjenesisException 位置: 类 org.springframework.objenesis.SpringObjenesis Error:(149, 35) java: 找不到符号 符号: 类 ObjenesisException 位置: 类 org.springframework.objenesis.SpringObjenesis
原因:
为了避免第三方class冲突,spring把最新的cglib和objenesis重新打包jar并没有放在源码里。解决办法:
gradle 执行 objenesisRepackJar 和 cglibRepackJar解决问题过程:
打开系统cmd 命令行控制台 (注意:不要用idea的 Terminal ,我一直不成功)
Win + R 输入cmd
切换工作目录到 spring 源码工程的根目录下
执行gradle objenesisRepackJar
和
gradle cglibRepackJar
idea 再次编译源码工程 Build -> Build Project
发现上述问题没有了 -
spring源码导入IDEA构建时报org.springframework.oxm.jaxb.test不存在问题的解决方案(spring-oxm缺少castor和jaxb)
然后重新build一下即可. -
找不到符号:类 JCacheCacheAspect、JtaAnnotationTransactionAspect、AnnotationTransactionAspect 、AnnotationCacheAspect 、AnnotationAsyncExecutionAspect 、AnnotationBeanConfigurerAspect
具体如下:D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\cache\aspectj\AspectJJCacheConfiguration.java Error:(42, 16) java: 找不到符号 符号: 类 JCacheCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJJCacheConfiguration Error:(43, 17) java: 找不到符号 符号: 类 JCacheCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJJCacheConfiguration Error:(43, 49) java: 找不到符号 符号: 变量 JCacheCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJJCacheConfiguration D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\transaction\aspectj\AspectJJtaTransactionManagementConfiguration.java Error:(43, 16) java: 找不到符号 符号: 类 JtaAnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration Error:(44, 17) java: 找不到符号 符号: 类 JtaAnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration Error:(44, 59) java: 找不到符号 符号: 变量 JtaAnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJJtaTransactionManagementConfiguration D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\transaction\aspectj\AspectJTransactionManagementConfiguration.java Error:(43, 16) java: 找不到符号 符号: 类 AnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration Error:(44, 17) java: 找不到符号 符号: 类 AnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration Error:(44, 56) java: 找不到符号 符号: 变量 AnnotationTransactionAspect 位置: 类 org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\cache\aspectj\AspectJCachingConfiguration.java Error:(42, 16) java: 找不到符号 符号: 类 AnnotationCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJCachingConfiguration Error:(43, 17) java: 找不到符号 符号: 类 AnnotationCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJCachingConfiguration Error:(43, 53) java: 找不到符号 符号: 变量 AnnotationCacheAspect 位置: 类 org.springframework.cache.aspectj.AspectJCachingConfiguration D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\scheduling\aspectj\AspectJAsyncConfiguration.java Error:(44, 16) java: 找不到符号 符号: 类 AnnotationAsyncExecutionAspect 位置: 类 org.springframework.scheduling.aspectj.AspectJAsyncConfiguration Error:(45, 17) java: 找不到符号 符号: 类 AnnotationAsyncExecutionAspect 位置: 类 org.springframework.scheduling.aspectj.AspectJAsyncConfiguration Error:(45, 62) java: 找不到符号 符号: 变量 AnnotationAsyncExecutionAspect 位置: 类 org.springframework.scheduling.aspectj.AspectJAsyncConfiguration D:\Idea2019\workspace-senior\spring-framework\spring-aspects\src\main\java\org\springframework\context\annotation\aspectj\SpringConfiguredConfiguration.java Error:(19, 49) java: 找不到符号 符号: 类 AnnotationBeanConfigurerAspect 位置: 程序包 org.springframework.beans.factory.aspectj Error:(47, 16) java: 找不到符号 符号: 类 AnnotationBeanConfigurerAspect 位置: 类 org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration Error:(48, 24) java: 找不到符号 符号: 变量 AnnotationBeanConfigurerAspect 位置: 类 org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration
原因:
通过百度查询到问题原因是spring源码的AOP使用了aspectj,而java不识别aspectj
下载AspectJ
https://www.eclipse.org/aspectj/downloads.php
安装
win10安装办法,在cmd窗口中执行
弹出
安装完
添加facet属性
选择spring.spring-aop.main
按照上述步骤添加spring.spring-aspects.main
最后的结果展示如图
更改编译器
3、创建测试项目
导入成功之后可以在project下创建一个自己的测试module
-
项目根目录右键 -> new -> module -> gradle
-
在新项目的build.gradle下添加对spring模块的依赖,这里我先添加了spring-beans 和spring-core的依赖。
dependencies { compile(project(":spring-beans")) compile(project(":spring-core")) testCompile group: 'junit', name: 'junit', version: '4.12' }
-
在新项目的src/main/resource下添加spring-config.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"> <!--把对象的创建交给spring来管理--> <bean id="person" class="com.wts.Person"> <property name="id" value="1"></property> <property name="name" value="zhangsan"></property> </bean> </beans>
-
创建测试bean和启动类
public class Person { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) ac.getBean("person"); System.out.println(person); } }
之后就可以愉快的调试spring源码了。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)