自己手动开发一个简易版SpringMVC框架
1 【骨架】项目框架搭建
使用Gradle进行依赖管理
- 首先在Idea中选择File—>New—>Project,在左侧选择Gradle—>Java,填写一些项目信息,这里名为mini-spring,创建项目完成
- 之后,在项目上右键New—>Module,在左侧选择Gradle—>Java,ArtifactId填为framework,创建模块完成
- 重复上面的步骤,创建一个名为test的module,作为测试mini-spring功能的模块
- 由于不需要在主模块下编写代码,删掉主目录下的src目录
至此,项目搭建完成,目录结构如下:
要编写自己的spring框架需要先了解真正的spring的主要结构,如图:
因此我们的mini-spring结构如下:
- 实现core模块,包括Beans、Core、Context包;
- 实现web模块,集成Web和WebMVC
- 添加starter,实现类springboot的启动方式
在framework模块中创建如下的package:
在test模块中添加启动类Application并添加main方法输出hello world语句。
在test模块中的build.gradle文件添加如下代码:
jar {
manifest {
attributes "Main-Class": "cn.edu.neusoft.Application"
}
from {
configurations.compile.collect() {
it.isDirectory() ? it : zipTree(it)
}
}
}
在terminal中使用gradle build
,java -jar
命令查看是否成功输出hello world
为了把framework模块打包到test模块中,需要在dependencies
中添加compile(project(':framework'))
,这样test模块打出的jar包就会包含framework模块的代码了
接着,在framework的starter包中建立一个类MiniApplication,添加如下方法:
public static void run(Class<?> clz, String[] args) {
System.out.println("hello mini-spring");
}
这样做是模拟了springboot的启动方法,在test的Application类的main方法中调用MiniApplication.run(Application.class, args);
重新执行gradle build
,java -jar
命令查看是否成功输出hello world和hello mini-spring
2 【载体】集成服务器之Web服务器&Servlet
由于服务器进程的编写涉及到Java的Socket编程、HTTP请求的封装和服务器IO等知识,较为复杂,这里我们的框架仿照springboot的方式内置一个服务器(Tomcat)。
集成Tomcat
① 首先要为容器引入一个Tomcat包,这里选择目前比较流行的8.5.23版本。在framework模块的build.gradle文件的dependencies中引入compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.5.23'
②在web包下新建一个server子包并创建TomcatServer类,添加如下代码:
public class TomcatServer {
//tomcat配置
private Tomcat tomcat;
private String[] args;
public TomcatServer(String[] args) {
this.args = args;
}
public void startServer() throws LifecycleException {
tomcat = new Tomcat();
tomcat.setPort(6699);//设置监听端口
tomcat.start();
//防止服务器中途退出
Thread awaitThread = new Thread("tomcat_await_thread") {
@Override
public void run() {
//声明tomcat一直在等待
TomcatServer.this.tomcat.getServer().await();
}
};
//设置线程为非守护线程
awaitThread.setDaemon(false);
awaitThread.start();
}
}
③在starter包下的MiniApplication类中添加
TomcatServer tomcatServer = new TomcatServer(args);
try {
tomcatServer.startServer();
} catch (LifecycleException e) {
e.printStackTrace();
}
④gradle build clean
后再执行java -jar test-1.0-SNAPSHOT.jar
看到控制台输出tomcat信息代表程序编写成功(此时浏览器访问http://localhost:6699会404,是因为我们还没有编写servlet处理请求)
⑤修改TomcatServer类的代码
public class TomcatServer {
//tomcat配置
private Tomcat tomcat;
private String[] args;
public TomcatServer(String[] args) {
this.args = args;
}
public void startServer() throws LifecycleException {
tomcat = new Tomcat();
tomcat.setPort(6699);//设置监听端口
tomcat.start();
//建立tomcat与servlet的联系
Context context = new StandardContext();
context.setPath("");
context.addLifecycleListener(new Tomcat.FixContextListener());
TestServlet servlet = new TestServlet();
Tomcat.addServlet(context, "TestServlet", servlet).setAsyncSupported(true);
context.addServletMappingDecoded(