JavaWeb开发

tech2024-07-04  59

          超凡论基础的重要性_1 JavaWeb项目搭建基础知识章节总结

                                                                                                                            作者:田超凡

版权所有,转载请注明原作者,仿冒侵权必究法律责任

搭建工具Idea 基础开发环境jdk1.7.79 tomcat7 maven3.3  pom依赖apache commons io,commons lang,tomcat maven plugin插件 servlet jsp ,需要指定scope provided,jstl需要指定scope runtime,mysql jar commons dbutil.jar解释这个是apache新出的一款轻量级的JDBC工具包 dbcp jat连接池 slf4j通用日志接口jar

其他jar包按需引用,以上jar只是基础依赖jar,注意着重强调不要在本框架中引用其他框架的jar包如spring springmvc mybatus等等,一方面避免破坏框架的独立性和完整性,自己开发的框架尽可能与其他框架隔离,一方面简化框架的体型。众所周知随着spring等其他javaweb框架的日益强大和功能日益完善,也带来了一系列问题,比如框架功能过多产生臃肿,自己开发的实际项目并不需要如此多的功能,此时就应该自己开发一款框架产品,一方面取其精华去其糟粕,一方面可以实现框架源码的自定义,真实的项目需要哪些功能就定义哪些,需要哪些注解,注解需要哪些功能都可以自定义,并且可以根据项目实际需要去逐渐完善,体量非常轻。但是需要申明的是,我根据教程开发自己的框架并不是想重新发明一个轮子,也并没有贬低spring的意思,这点必须承认。我只想把相对而言更加对的轮子装上我自己更加对的马车上。简而言之就是我想给已经比较契合的轮子刷上属于自己的颜色,刻上自己想要的图案,但是并不想把这个轮子替换掉那个通用的用途广泛的轮子。在我的这段话中通用的广泛的轮子可以理解为spring,而我自己的smartframework当然就可以简单理解为那个自定义的轮子了。

开发过程流程概述与注意问题说明 首先需要定义各类工具类,如CastUtil类型转换工具类 ArrayUtil数组工具类 JsonUtil工具类序列化和反序列化json CodeUtil工具类对url参数进行编码和解码,StreamUtil工具类用来操作常用的文件流 PropUtil工具类读取属性配置文件等等 具体实现细节较为简单此处不再赘述 接下来就需要定义一些核心的助手类了 类加载器ClassHelper 可以根据类名,包名递归扫描所有的类,还可以定义类加载器以及通用的加载类到加载器池的方法,具体实现细节不再赘述,需要强调主要依赖反射机制,关于java反射方面的知识请自行查看java.lang.reflect相关类的源码. 实现过程简述 首先定义类加载器放到静态代码块,确保先初始化类加载器classloader,其次根据包名生成resource路径,根据resource路径操作文件流获取路径下的所有file 迭代这些file并判断是文件还是目录,如果是文件,则取到文件名判断后缀是否是class如果是把文件名取到也就是类名,调用方法基于反射机制把通过类名获取类的信息比加入一个自定义的类容器。如果是目录,则取到目录的路径和目录的包名,根据目录的路径再次递归调用该方法,依次读取所有的类文件,根据类文件名依次通过反射获得类并加入类容器。这里的类容器是一个单例的,你可以把他定义成一个set集合。为什么不用list?当然是因为不同包下面可能存在同名的类,用list可能获取多个同名的类,但是set是基于hash算法实现的元素唯一并且没有顺序,无论是性能方面还是在此处的作用方面均由于list,但是需要强调的是,这个set一定要是单例的,即满足单例设计模式的规范和要求去定义,推荐静态内部类不要用懒汉饿汉,确保线程安全的同时也延误了延迟加载,相关实现原理和细节不再赘述,请自行查看spring的源码以及设计模式的基础知识学习。如果到这里你已经发现有些不太明白了,那就建议你不要往后看了,先去补一下框架的基础知识再继续,这样效果会好一点。

类加载器定义之后还需要定义什么呢?没错,就是注解了。目前可以需要先定义四种类型的注解,控制器注册注解,业务层注册注解,映射请求方法的注解,依赖注入实现自动装配的注解。具体实现细节请查看spring源码进行学习,然后再自定义,需要使用target和retension相关注解定义,定义注解关键字不是class而是@interface.此处不再赘述其他的可以以后按需定义,避免代码臃肿,多了不必要的功能造成严重的性能开销很不划算,内存溢出的异常已经见了太多,所以一定要注意。 然后就是要定义一个助手类来调用类加载器的方法来读取不同类型的类并进行分类,如只读取控制器类,业务类等等,需要使用isAnnotationPreset方法加以判断,作用和原理可以参考spring开发手册和源码。然后要定义一个映射助手类来存放具体的类和实例的映射关系,具体的类通过调用类加载器助手类基于反射机制获取所有类,并定义基于反射机制并根据具体的类生成实例的方法,迭代并放入映射集合。再来开发一个本框架的核心工具类,iocutil,用来定义IoC容器并实现di依赖注入,简要描述实现方式,获取到映射类定义的所有类和实例的映射集合,进行迭代,分别取到原型类和实例,然后根据原型类获取类中定义的所有field成员变量并迭代调用辅助类方法赋值,看上去并不复杂,但是前提是前面的步骤已经非常完善,否则后患无穷需要注意。我只是简单的进行了描述,毕竟具体的实现原理得靠自己一点一点去摸索和钻研才能体会到其中的精华。然后就是定义控制器组件了,需要单独定义出request类和handle类,并建立二者的映射,request类主要存放请求路径和请求方式,handle则主要存放控制器类的原型和其中定义的方法原型集合。在控制器助手类同样遍历req和handle之间的映射集合分别取到请求url method并和每一个method根据正则匹配,匹配成功之后就通过反射调用方法原型并执行得到方法执行返回值,再判断返回值类型是view还是data,如果是view则代表返回的是逻辑视图名,直接转发或者重定向,因为暂时还没有定义和配置本框架的视图解析器,所以暂时不用考虑拼接url规则,可以加一个TODO等需要时加入匹配规则之后再渲染视图响应客户端。如果是data则代表返回的是json格式的或者直接可以响应前台的ajax回调结果数据,可以根据需要调用jsonutil的方法对数据进行序列化或反序列化之后再写到输出响应流返回给前台。具体实现细节不再赘述。再来开发框架的核心控制器SmartServlet,具体实现细节和原理可以学习参考springmvc核心控制器dispatcherservlet的实现原理和源码,本核心控制器也是基于seevlet实现,所以要继承HttpServlet并重写init和service方法。init方法初始化时需要调用类加载器加载所有控制器类和业务类,在service方法中遍历req handle映射的集合,分别取到每一个req和 handle,将请求参数以键值对的形式存放在一个param类中并调用控制器辅助类的注册方法执行即可,此处不再赘述,时间关系先介绍到这里,有不对的地方欢迎批评指正。

最新回复(0)