spring系列1-基于源码搭建普通工程&web工程

目录

前言:工欲善其事,必先利其器

一、下载源码

方式1 - github

方式2 - gitee码云

二、准备gradle

1. 下载

2. 解压文件

三、导入源码

四、编译准备

1. 解决问题

2. 手动build

五、创建自测的gradle项目

1. 普通Java项目

(1)新建

(2)引入依赖

(3)写demo

(4)解决问题

2. springmvc项目

(1)新建

(2)引入依赖

(3)完善目录结构

(4)项目配置

(5)引入其它spring模块的问题


前言:工欲善其事,必先利其器

目前还在摸索spring源码阅读,但是深有体会,阅读源码要一边看博客、书籍资料,一边debug源码,有些自己疑惑,但资料没解释清楚的,就要靠运行demo,debug源码理解了。

看了《spring源码深度解析》的spring环境搭建,也搜了很多博客,但是千人千面吧,会遇到别人没遇到的问题,或者别人的方式不适用,特此记录,仅供参考(ps:我的硬件环境是mac)。

tips:解决了"五-1-(4)-问题②"后,我意识到:gradle版本会影响环境搭建,最好使用源码指定的gradle版本,比如5.1.x spring指定gradle-4.10.3:

一、下载源码

方式1 - github

通过github的spring-framework项目地址:GitHub - spring-projects/spring-framework: Spring Framework

如果github无法访问,参考:Mac 无法访问github - 简书

方式2 - gitee码云

github拉取(或下载)代码太慢了!!!解决方案参考:解决Github代码拉取速度缓慢问题

总结:先用gitee从github拉取代码,再通过gitee下载或clone

二、准备gradle

我用的是gradle-4.4.1-all.zip搭建

1. 下载

传送门:Gradle | Releases,下载有点慢

2. 解压文件

放在这个目录下:/Users/你的用户名/.gradle/wrapper/dists

ps:尝试过放在其它自定义目录,但是通过idea导入工程的时候会报错

三、导入源码

我的IDEA版本是2018.3.6

ImportProject => 选择gradle => 指定gradle目录、其它选项 => finish

第1步第2步第3步

四、编译准备

import项目,idea会自动尝试构建build,也可以手动触发

1. 解决问题

错误①:No such property: immutableValues for class: org.gradle.api.internal.tasks.DefaultTaskDependency

错误发生的位置:spring-beans项目 => spring-beans.gradle文件 => 最后几行

搜了很多博客,都是建议注释掉29、30两行,暂且照做,会给后期埋坑。心急看解决方案的可以直接看:"五-1-(4)-问题②"

错误②:Could not find method useJUnitPlatform() for arguments [spring_test_edty6ooeo2ucmkfu517bbq0z7$_run_closure4$_closure14@1eef8099] on task ':spring-test:junitJupiter' of type org.gradle.api.tasks.testing.Test.

错误发生位置:

遵从大众方案:注释掉101~104行

2. 手动build

可以看到idea在唰~~唰~~地下载jar包。玩了会手机后再看,还在下载,甚至会timeout中断下载(内心。。。。)

解决方案:增加阿里云镜像仓库!!在project的build.gradle文件的2处增加如下配置:

maven{ url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven{ url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}

新增仓库后,再手动build。等待一会,可以看到如下图,build成功了😊,spring模块都有蓝色方块了。如果build的过程还报一些非代码问题,就再手动build两次试试。

继续踩坑之旅。。。。。

五、创建自测的gradle项目

1. 普通Java项目

(1)新建

右键 => new => module => 选择gradle、选择java => next => 填入artifactId => next => finish。又是一阵自动build,还是成功的😊

(2)引入依赖

比如spring-aop模块引用了spring-core模块、spring-beans模块(提供ioc功能),可以通过spring-aop.gradle看到是如何引用的。

咱们有样学样,也粘贴这两行,毕竟阅读spring源码第一步就是阅读IOC,引入依赖:

(3)写demo

具体就不展开了,包括spring配置文件、bean、单测,主要是为了看getBean执行逻辑:

运行单测,迎接新坑出现。。。。。

(4)解决问题

问题①:cglib相关不存在

打开idea侧面的Gradle工具,找到spring-core => other => 双击cglibRepackJar即可,顺便双击objenesisRepackJar吧,因为待会就是报错找不到它😹

双击完上面两个后,单测顺利运行了!

问题②:有时候还会遇到报错:Circular dependency between the following tasks(如果没遇到,手动双击spring-beans的build试试😏)

对于Circular dependency问题,搜到有些博客是让我恢复之前注释的内容(见4-(1)-错误①),比如:编译spring源码Circular dependency between the following tasks - ymgydx的个人空间 - OSCHINA - 中文开源技术交流社区。恢复之后,又会报错:No such property: immutableValues for class: org.gradle.api.internal.tasks.DefaultTaskDependency(😹😹这不是死循环吗??)

解决方案:我琢磨no such property,那这个类有啥property呢,顺着包路径瞅到一个values属性,如下图:

抱着试试看的心态,做了如下修改:

def deps = compileGroovy.taskDependencies.immutableValues + compileGroovy.taskDependencies.mutableValues

改成:

def deps = compileGroovy.taskDependencies.values

然后,就顺利build了😊。接下来就可以自由发挥,写ioc、aop的测试demo了。

2. springmvc项目

这里的配置主要参考了2篇博客:

IntelliJ IDEA配置Web项目 - 简书:解释了IDEA的Facets、Artifacts,讲得很好

Spring源码——SpringMVC测试工程搭建_spring源码测试springmvc_等一杯咖啡的博客-CSDN博客:基于源码搭建springmvc工程

(1)新建

右键 => new => module => 选择gradle、选择java、选择Web => next => 填入artifactId => next => finish

(2)引入依赖

compile(project(":spring-web"))

compile(project(":spring-webmvc"))

(3)完善目录结构

我从其它springmvc项目中拷贝了WEB-INF目录及其子目录:

目前的目录结构期望的目录结构

(4)项目配置

第1步:project structure配置 => 新建Facets第2步:选择spring-mywebtest_main模块 => ok第3步:地址调整

Path:

修改前:/.../spring-framework/.idea/modules/spring-mywebtest/web/WEB-INF/web.xml

修改后:/.../spring-framework/spring-mywebtest/src/main/webapp/WEB-INF/web.xml

Web Resource Directory:

修改前:/.../spring-framework/.idea/modules/spring-mywebtest/web

修改后:/.../spring-framework/spring-mywebtest/src/main/webapp

第5步:将依赖的springwebmvc、springweb源码、配置文件一起打包,这里再给“等一杯咖啡”博主点赞(原文)。如果不打包,直接配置tomcat运行会报错:

One or more listeners failed to start. Full details will be found in the appropriate container log file

实际就是找不到spring-web中的ContextLoaderListener类,虽然自己明白问题在哪,之前不知道如何打包其它spring项目。

第4步:新建artifacts

第5.1步:打包spring-webmvc_main、spring-web_main源码

第5.2步:打包spring-webmvc_main、spring-web_main的配置

①选中classes

②选择Module Sources

第5.3步:打包spring-mywebtest项目自己的资源文件夹(同5.2相似):①选中classes;②选择Directory Content;③选择spring-mywebtest项目的resources文件夹

打包结果如下:

最后配置tomcat启动即可。

(5)引入其它spring模块的问题

dispatchServlet.xml中引入其它spring模块的标签,比如使用context:annotation-config、context:component-scan标签:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.webtest"/>
    ...
</beans>

spring-mywebtest启动时会报错:

信息: Initializing Spring DispatcherServlet 'dispatcher'
ERROR DispatcherServlet Context initialization failed
 org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]
Offending resource: ServletContext resource [/WEB-INF/dispatcher-servlet.xml]

	at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:72)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:119)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:111)
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:281)
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1388)

意思是无法定位到http://www.springframework.org/schema/context对应的spring-context.xsd的解析器。

实际工程应用中引入spring各模块的依赖,每个spring模块的resources文件夹中的配置文件都在类路径的jar包中,不会遇到问题。

而基于spring源码搭建的项目,虽然引入了spring-mvc模块,间接引入spring-context等模块,但没有将其它模块打包,因此项目文件中只保留了spring-mvc模块的spring.handlers、spring.schemas文件,如下图:

我没找到办法将spring-context等模块打包到lib目录中,但是想到其它有效的旁门左道:将spring-context模块中spring.handlers、spring.schemas文件的内容复制粘贴到spring-mvc模块的对应文件中,项目就可以启动了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值