• 实现ComponentScan注解,根据指定包名扫描


    前言

    手写web服务器,到今天已经实现了controllerRequestMappingRequestParameterService还有简易的Ioc,从构成要素上将我们的小项目已经算是一个比较完整的服务器了,但也有很多需要优化的地方,今天我们就来实现ComponentScan注解,优化一下包扫描,实现可以根据我们指定的包名进行组件扫描。

    这个注解,功能上我们参考了spring,因为是纯手写,所以我们并没有去看spring的源码,最近确实也没时间看。

    整起来

    今天核心的工作就两个,首先是定义一个新的注解,然后我们根据这个注解去扫描指定的包。如果注解不存在,我们就从服务器入口,即SyskeBootServerApplication类所在包开始扫描。

    定义ComponentScan注解

    现在定义注解以及是轻车熟路了 ,so easy!这里的value() 方法定义的是数组,用于接受需要扫描的包名,也就是说我们也是支持多包名的。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ComponentScan {
        String[] value() ;
    }
    

    然后把ComponentScan注解加在我们服务的入口上:

    为什么要加在服务器入口上呢?这是我人为规定的,现在还没有实现Configuration注解,加在服务器主入口是最好的选择。

    优化包扫描器

    根据注解内容优化包扫描器:

    /**
         * 扫描指定的包路径,如果无该路径,则默认扫描服务器核心入口所在路径
         * @param aClass
         * @throws IOException
         * @throws ClassNotFoundException
         */
        private static void componentScanInit(Class aClass) throws IOException, ClassNotFoundException {
            logger.info("componentScanInit start init……");
            logger.info("componentScanInit aClass: {}", aClass);
            Annotation annotation = aClass.getAnnotation(ComponentScan.class);
            if (Objects.isNull(annotation)) {
                Package aPackage = aClass.getPackage();
                scanPackage(aPackage.toString(), classSet);
            } else {
                String[] value = ((ComponentScan)annotation).value();
                for (String s : value) {
                    scanPackage(s, classSet);
                }
            }
            logger.info("componentScanInit end, classSet = {}", classSet);
        }
    

    在服务器启动时,需要先执行componentScanInit方法,这个方法需要传入一个Class,也就是我们项目的主入口的类。

    方法内部会先判断这个类是否有ComponentScan注解,如果有则根据注解value()的值进行扫描,否则拿到传入类的包路径,然后开始扫描。

    测试

    运行启动下,我们发现控制台已经打印出了扫描到的类:

    总结

    今天的内容依然很简单,就只是实现了一个注解,然后根据这个注解优化了我们包扫描的业务代码,没有什么复杂的知识点,后面我们还需要对很多功能进行优化,包括以下几点:

    • post请求处理与响应
    • GetMappingPostMapping的实现,这个两个注解实现起来很简单了,和RequestMapping基本上一致
    • 配置注解的实现:valueConfigurationProperties
    • get请求页面模板实现
    • 集中异常处理

    目前大概能想到这几点,其他的等后面再说。明天应该会先解决post请求这块,思路已经有了。好了,今天就先到这里吧!

    下面是项目的开源仓库,有兴趣的小伙伴可以去看看,如果有想法的小伙伴,我真心推荐你自己动个手,自己写一下,真的感觉不错:

    https://github.com/Syske/syske-boot
    

  • 相关阅读:
    IntelliJ IDEA导包快捷键
    maven命令创建web骨架项目
    v2.0版本小程序开发心得(代码之外)
    装饰器模式
    闭包
    git diff的文字说明
    WSGI和CGI
    word-wrap、white-space和word break的区别
    Javascript中正则的 match、test、exec使用方法和区别
    Git 内部原理
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/14866552.html
Copyright © 2020-2023  润新知