一、前言
最近开始研究一些优秀的JavaWeb开源项目,由于自己是新手,以前遇到开源项目时也处理得不是太好,往往浪费很多时间,希望在本次研究的过程中总结出一套方法论来,因此有了这一系列文章。
二、正文
1. 首次运行
拿到一个开源项目,第一步要做的一定是把它跑起来,而这个过程又包含了以下几个小步骤,只有全部搞定后项目才能正常运行。
(1)引入依赖
大多数Java项目采用Maven管理依赖,需要我们在计算机上配置好Maven的环境,其中需要注意的点主要包括:中央仓库镜像的配置,项目独立仓库的配置,项目依赖包版本的确认(某些包的古老版本可能不存在);
(2)关联程序的配置
JavaWeb项目一般会连接数据库,因此可能需要安装配置MySQL或其他数据库,在这个过程中需要注意的问题主要包括:数据库的版本需要与Driver适配,项目中配置的数据库用户必须具有访问权限;
(3)编译构建
JavaWeb项目的构建方法有很多种,当下流行的IDE(Eclipse/Idea)基本也都自带构建功能,此外还可采用Maven来进行构建,但这两种构建方式必须区分清楚,理解其原理才不会掉进坑里,如果项目原作者采用的是IDE构建,而没有把构建相关配置写入pom文件,那么我们如果使用Maven进行构建就会出现问题,以下是两种构建方式的操作方法:
a)IDE构建
通过IDE对项目进行配置,指定源码位置,资源文件位置,构建输出文件位置,构建包类型等,一切都可以通过图形化界面操作完成,Mark as resources root,对于Web项目,然后只需要配置一个Web容器(Tomcat、Jetty等)即可;
b)Maven构建
由pom.xml文件中的标签完全负责,需要在标签内指定源码位置,资源文件位置,构建包类型,包文件名等,必须通过自己写xml标签的方式来实现,需要注意的是,某些配置文件不仅存在于resources文件夹下,也存在于java包内(如MyBatis配置文件),这部分文件的构建需要单独指定;
二者比较:使用IDE构建在图形化界面操作即可,比较方便,但是具有本地性质,图形化界面的操作最终应该也是映射为了某一个IDE的配置文件,但是不能体现在项目源码中,对于开源项目来说,我觉得采用Maven构建的方式更好,因为项目的使用者需要尽可能多地获取项目的所有配置,因此将配置体现在源码中更为妥当。
2. 分析源码切入点
(1)JavaWeb项目的切入点(以SpringBoot项目为例)
在一起配置妥当之后,项目终于跑起来了,接着就是分析源码,简单的项目通常包含几十上百个文件,复杂的项目则可能有成千上万个文件,那么从哪里切入?
根据软件设计的高内聚低耦合原则,对于一个Web项目,处理每一次请求所要运行的代码应当是非常少量的,那么如何从庞大的代码库中定位到处理本次请求的那一部分代码呢?
以下给出两种思路:
a)由URL路由入手
无论是Servlet还是各种MVC框架,每个URL都会对应一个处理的类或方法,一般结合注解或者配置文件通过DispatchServlet等中间处理器进行URL路由,对于SpringBoot项目来说,则是在RequestMapping注解中指定URL了,因此想到的一种切入方法就是在所有Controller类中搜索想要查找的URL,就能找到处理该URL请求的方法,进而进一步跟踪代码执行;
然而我认为这种方式是有局限的:
首先,JavaWeb容器是提供了filter接口的,对于某些请求可能在filter阶段就被驳回,根本到达不了Servlet阶段;
其次,URL搜索的方式依赖于IDE提供的全文搜索功能,本质上是一种遍历的方式,即使加了索引优化也会带来很大的CPU与内存资源消耗,在项目十分复杂的情况下可能表现并不好;
正是考虑到以上两点局限,所以思考了接下来的第二种思路。
b)由Filter入手
既然Web容器处理请求的顺序是先过Filter,再用Servlet处理,那么第一个Filter其实也就是一个很好的切入点,如果我们写一个DebugFilter加入到项目中,并配置其顺序为首个Filter,那么顺藤摸瓜分析doFilter方法的调用栈就能够很容易找到项目中真正处理请求的代码了。
说到Filter就想了解一下Web容器中的多个Filter的组织、调用关系,这里计划新开一篇文章来写:Tomcat ApplicationFilterChain源码分析(职责链模式)。