实现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

原文地址:https://www.cnblogs.com/caoleiCoding/p/14866552.html