手写Spring之实现SpringBoot启动
写在前面
最近学习了一下spring的相关内容,所以也就想要照猫画虎地记录和实现一下spring的框架,通过阅读这些也希望能够消除对Spring框架的恐惧,其实细心阅读框架也很容易理解。
mini-spring尽量实现spring的核心功能。文章写得很仓促,可能不是很全面,在全部完成之后我们再来完善表达吧,见谅~
项目的源码我放在了github上:源码地址
我会在这里整理文章的系列目录:
- 从头开始实现一个小型spring框架——手写Spring之实现SpringBoot启动
- 从头开始实现一个小型spring框架——手写Spring之集成Tomcat服务器
- 从头开始实现一个小型spring框架——控制器controller的实现
- 从头开始实现一个小型spring框架——实现Bean管理(IOC与DI)
一、Spring家族体系
关于spring家族体系的介绍,欢迎移步我的另一篇博客,这里有对Spring发展历史的一些介绍。
直达链接--------->>> 理解Spring家族生态体系
当然,你只需要知道Spring的核心机制,如IOC和AOP等内容,就可以开始阅读下面的内容了。
二、Gradle介绍
2.1 Gradle 产生背景
随着敏捷开发实践的崛起,人们从 XML 文件的构建方式,寻求一个可表达且可维护新的构建工具。Gradle就是满足这种需求的新的构建工具。
2.2 Gradle 优势
Gradle 是基于 JVM 构建工具的新一代版本,它融合了 Ant 跟 Maven 中的优点,并且将其优点发挥更加极致。
Gradle 使用了基于 Groovy 的 DSL,摈弃 XML,更加强大跟表达性强。开发者可以使用 Java,Groovy,Kotlin 等语言去编写构建逻辑。
Gradle提供了一套依赖管理方式,不仅高度可配置,而且能够 Maven,Ivy 相兼容。Gradle 的依赖管理不仅限于外部库,同时还支持多项目构建,项目之间依赖建模。
Gradle 还支持对 Ant 跟 Maven 的构建项目进行无缝迁移。
2.3 为什么使用Gradle?
因为之前很少使用gradle进行项目构建,也为了自己学习一下,所以就选择了gradle,并没有什么特殊情结~。如果你之前就已经很熟悉maven的项目构建和模块管理,那么你可以很快地无痛切换到gradle,而且使用gradle会让你的依赖看起来更加简洁。
三、项目结构
本项目使用gradle进行构建,其中mini-spring为根模块,包含两个子模块:framework模块和test模块
3.1 主模块
3.2 framework模块结构
framework模块为mini-spring项目的框架核心,用于实现spring的核心功能,可类比于开发中需要引入的jar包,为我们的test模块提供支撑。
我们使用包代替spring中的各种jar结构,其包结构为:
- beans:负责spring的bean的维护
- context:提供spring根据不同场景提出来的框架接口
- core:spring框架里经常用到的工具包
- starter:实现类似SpringBoot的启动方式
- web:实现web相关的功能
3.3 test模块结构
test模块是我们的应用模块,为我们的mini-spring框架提供测试,以验证framework内容的正确性、并反馈框架中存在的问题。
这是我们的最终的包结构
四、实现步骤
有了上一小节对结构的叙述,我们接下来来对我们的mini-spring框架进行具体实现
- 首先创建gradle项目,命名为mini-spring。并新建两个子模块 framework、test。
mini-spring的build.gradle
plugins {
id 'java'
}
group 'com.qcby'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
subprojects {
}
framework的build.gradle内容
plugins {
id 'java'
}
group 'com.qcby'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
}
test模块的build.gradle
此处我们了配置打包方式为jar的打包方式,以便于我们直接使用jar包的方式运行程序。
并且将项目的启动类Main-Class配置为com.qcby.Application。
plugins {
id 'java'
}
group 'com.qcby'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile(project(':framework'))
}
jar{
manifest {
attributes "Main-Class":"com.qcby.Application"
}
from{
configurations.compile.collect{
it.isDirectory() ? it : zipTree(it)
}
}
}
下面是我们对启动器的具体实现:
framework模块:
在framework模块下的starter包中新建一个类,命名为MiniApplication
package com.qcby.starter;
/**
* @author kevinlyz
* @ClassName MiniApplication
* @Description 框架的入口类
* @Date 2019-06-04 19:21
**/
public class MiniApplication {
public static void run(Class<?> cls,String[] args){
System.out.println("Hello mini-spring application!");
}
}
我们在这里打印一句 Hello mini-spring application! 以验证程序是否正确启动。(之后我们的还要对程序进行一步步的完善)
test模块
我们在test模块的跟目录下仿照springboot的启动方式,新建一个Application启动器,用于程序的启动。通过static调用的方式传入我们的类信息,并调用MiniApplication的run方法启动程序。
package com.qcby;
import com.qcby.starter.MiniApplication;
/**
* @author kevinlyz
* @ClassName Application
* @Description TODO
* @Date 2019-06-04 19:02
**/
public class Application {
public static void main(String[] args) {
//测试打印
System.out.println("Hello World!");
//启动方法
MiniApplication.run(Application.class,args);
}
}
五、测试
上面就是我们的starter启动器的全部代码了,仅仅一个静态调用就可以实现了。hh,太短了是不是,很简单是不是?额,不过确实已经实现了。
我们在test模块的gradle配置中已经设置了main启动类,并且设置了项目的打包方式,接下来只要简单的build一下就可以完成打包。
选择我们的mini-spring根模块进行构建,可以看到在每个模块的目录下各自新生成了一个build文件夹,其中包含了一个libs目录,在libs目录中存放的就是我们最终生成的jar包了。
接下来进入我们的terminal(可以在idea下的terminal进到相应的目录,或者windows的控制台,或者mac的terminal,不过多叙述)
像springboot一样,我们输入命令:java -jar test/build/libs/test-1.0-SNAPSHOT.jar
就可以看到我们的MiniApplication成功启动了,并且在控制台输出了 Hello mini-spring application! 的内容。打印出mini-spring application代表着我们的framework内容被成功地调用了,如下图所示,
至此,我们mini-spring框架的启动器就完成了!!
四、小结
本篇文章在于对框架的包结构以及各个包需要实现的各个功能进行叙述,并对框架的starter启动器进行了实现。项目使用gradle进行项目构建,首先新建了framework和test两个模块,framework负责实现spring的核心功能,并且使用包名对各个功能进行了划分;test模块则负责对framework模块代码的正确性进行验证。
在完成了项目目录结构的分析和创建后,我们对框架的starter启动器进行了实现,Application通过调用MiniApplication的入口run方法启动整个程序,并在程序启动成功后输出相应的结果。
项目中framework模块为test模块提供了支撑,test模块则反过来为framework模块提供验证。
我们后续将继续逐步对mini-spring框架进行完善,并完成相应功能的开发。在下一篇文章中,类似于springboot,我们将将把tomcat容器集成进我们的mini-spring框架之中,并对spring的DispatcherServlet进行具体的实现。
如果你感觉这篇文章对你有所帮助,麻烦点个赞呀~~