简单实现web框架的核心部分,包含反射,ioc,依赖注入,后续加入参数注入以及动态代理

模仿基本的web框架。

码云代码链接

  1. 配置:先从最简单的变量配置开始,后续手写xml解析器添加上去。
  2. 注解:包含controller注解,被该注解标记的类是控制器,@requestMapping注解,配置路由的url
  3. 依赖注入:使用@Inject注解,可以配置需要注入的类,以及主要注入类的实现类
  4. ioc容器,基本的注解扫描后的类对象都会存放在此处,使用的是Map<Class<?>, Object>来实现类的单例对象。

基本的实现思路:

  1. 设置注解,这里用到的注解一般都为运行时的注解,因为需要根据反射获得该注解以及对应的值
  2. 实现文件(包)的扫描的扫描器
  3. 使用IOC容器实现类和对象的映射,用来存放类对应的对象,这样就能保证任何基于该类的反射操作的对象是唯一的那个对象
  4. 使用Map存放url和对应需要执行方法的映射

基本的实现历程:

  1. 刚开始就只想做个简单的可以配置controllerrequestMapping的简单反射练习。

  2. 其中首先碰到的问题就是如何找到这些注解,参考了朋友李xx的答案,可以建立一个文件扫描,把配置的包进行一遍扫描即可。

  3. 再者碰到的问题就是如何根据url可以找到对应的类,最初实现的思路就是参考jfinal的概念,设计了Action的概念,我决定使用Action来表示一次请求,反射操作的对象就保存在Action中,此时的Action设计如下。

    public class Action {
        // 保存需要的类对象
        private Object classObject;
        private Method method;
        private Object[] args;
        // 这个方法是我当时设计的一个错误,还是记录下来吧
        public void keepClassElseClear() {
            this.method = null;
            this.args = null;
        }
    }
    

    因为当时的我搞混的一个概念,所以这块成为最后调试的一个大bug,在这里先说一下吧,就是我当时是这样设计的,因为一个类有很多方法,所以我觉得把单个类的对象保存下来,因为类对象是相同的,我想到对象可以复用,觉得清除类对象以外的就好了,然后就写出了如下代码。

    public void assembleMethodLevel(Class<?> cls) {
        final String className = cls.getName();
        Action action = new Action(cls);
        for(Method method : cls.getDeclaredMethods()) {
            action.keepClassElseClear();
            action.setMethod(method);
            // 等等
            putActionInUrlMApping(cls + '/' + method.getName(), action);
        }
    }
    

    当然,一眼就能看出来这个问题在哪,我以为对象能复用,然后每次只需要修改method就好了,然后把它放入url和mapping映射的Map中。这样做的后果就是对象是固定的,所以放入的映射全部都会指向一个对象。

  4. 当时实现的简单,测试的方法也只有一个方法,所以没有什么大问题,想到有点简单,而且在我实际操作过程中,有使用到很多显式new的对象,然后我就觉得有点混乱,不方便修改,而且很麻烦,就想到加入一个依赖注入

  5. 此时,我先前设计的弊端就暴露出来了,把对象放在Action中,依赖注入的类对象和Action对应的对象,二者反射的对象不一样怎么办,我就想到线程池,(虽然我没有用过线程池,但是我觉得这种思想可以借鉴),然后我决定设计一个类和对象映射的ObjectPool,相当于对于每个类只创建一个对象,然后把它们放入一个Map<Class<?>, Object>中,这样,就保证了类对象的单例,我觉得这算是一种对象复用吧。因此设计了我认为的ObjectPool,好像这个是叫IOC吧,我也不知道,关于依赖注入和动态代理我都是在一个公众号码农翻身上面找到的,通俗易懂,根据那个我很快理解了这些概念。十分推荐。

  6. 介于我之前看过的书重构,改善既有代码的设计,我的功能调整的很轻松,因为都比较通俗,代码组织我个人感觉还可以,所以,马上就做了修改,成效不错,成功了。

  7. 对于之前设计的很多接口,后续很多都删掉了,没有用,但是还有一个扫描的接口让我觉得大有可为,我就加上了,可以进行控制器以及依赖注入的扫描,将其分开,再加入新的东西,直接放进去就可以。

  8. 后续会补上AOP动态代理,以及支持Action的参数注入,以及一个简单的XML解析器


码云代码链接

发布了76 篇原创文章 · 获赞 53 · 访问量 4146

猜你喜欢

转载自blog.csdn.net/qq_42254247/article/details/104876362