这几天在家写了一个简陋版的SpringMVC,先把代码贴出来,有兴趣的同学可以看一下。
这里用了线程池来处理多个socket连接。
接着我们需要自定义一个Request和Response两个类来处理请求和响应信息。
Request这里存了请求头信息、请求参数信息、请求类型、请求URI等。Request的代码如下:
Response这里只处理了返回简单字符串和返回静态资源文件,Response的代码如下:
这里我们模仿Servlet,也自定义一个Servlet接口。代码如下:
它的一个实现类如下,在这个类中我们根据URI找到对应的请求处理类,并调用响应的请求方法。
接着我们模仿Spring写几个注解:
模仿Spring的Autowire注解
模仿Spring的Component注解:
模仿Controller注解:
模仿RequestMapping注解:
这里根据请求找到对应的处理类和处理方法的思路是:定义一个Map,key是请求URI,value是自定义的一个类。这个自定义的类(RequestMappingInfo)包含这几个信息:Class信息、Method类、对象、请求参数和方法参数。java类在编译为class的时候有release和debug模式之分,在命令行中直接使用javac进行编译的时候,默认的时候release模式,使用release模式会改变形参中的参数名。而IDE都是使用debug模式进行编译的。ant编译的时候,需要在ant的配置文件中指定debug="true"。
如果要修改javac编译类文件的方式的话,需要指定-g参数。即:javac -g 类文件。通常我们都是用IDE进行项目开发的,所以我们的java类在编译成class的时候参数是不会变的,而SpringMVC在处理参数这个地方用到了ASM技术,来获取参数的信息,并且是在第一次处理请求的时候,来获取参数信息并放到缓存中,以后都从缓存中获取参数信息。RequestMappingInfo代码如下:
接着我们定义一个类方便IOC:
接着就是我们比较重要的类了ApplicationContext,我们会在这里类中,简单模仿Spring IOC的过程,扫描固定包下固定注解的类。在这里遇到了一个问题,一开始在加载类的时候自己写了一个类加载器,但是一个类加载器在他的生命周期中只会加载这个类一次,所以会出现多次加载同一个类的情况。后来别人推荐了一个小工具类:Reflections,这个问题才比较完美的解决,Reflections是一个很不错的工具类,可以扫描Classpath下面任意的类,并且让反射更容易。如下:扫描带某个注解的类,获取含有方法名为某个字符串的类等等。github地址在这儿:https://github.com/ronmamo/reflections,里面有很多例子。自定义的ApplicationContext的代码如下:
下面我们写个Controller类来测试一下:
我们在浏览器中输入:http://localhost:8005/custom/myFirstPage.do来看一下结果:
控制台输出如下:

返回结果如下:
和我们程序写的结果一样。
接着我们写一个稍微复杂一点的,定义一个javaBean、DAO类、Service类。
UserScope
DAO
Service:
从上面的代码中我们可以看到在DAO的实现类上我们用了CustomComponent注解,在Service的实现类上我们用了CustomService的注解。在我们的那个Controller中我们又用了CustomAutowire这个注解。下面我们访问一下看看效果,我们在浏览器中输入:http://localhost:8005/custom/inserUser.do?userName=hangssewe&passWord=2ewewe
浏览器输出为:
我们在Controller中的inserUser这个方法中设置了两个Cookie,我们来看一下Cookie有没有设置成功:
结果和我们预想的是一样的。
接着我们写一个静态资源的处理类:
访问一下看看效果如何:
这里遇到的一个问题是在Chrome浏览器中访问的时候会报错,在IE浏览器中访问则正常显示,还没搞清楚为什么会出现这样的问题。