<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每日一例 | 手寫(xiě)web服務(wù)器:實(shí)現(xiàn)全包掃描和簡(jiǎn)易IOC

          共 7615字,需瀏覽 16分鐘

           ·

          2021-06-07 11:00

          前言

          最近寫(xiě)web服務(wù)器優(yōu)點(diǎn)上頭,根本停不下來(lái),對(duì),我就是卷王本卷,昨天實(shí)現(xiàn)了前端有參方法的調(diào)用,趁著這股熱勁,今天我們來(lái)實(shí)現(xiàn)下IOC容器,從原理和實(shí)現(xiàn)上來(lái)講,都不難了,因?yàn)槲覀冊(cè)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">controller和requestMapping注解實(shí)現(xiàn)的時(shí)候已經(jīng)驗(yàn)證過(guò)了,沿著同樣的思路搞就行了。好了話(huà)不多說(shuō),直接開(kāi)整。

          開(kāi)整

          同樣是基于我們之前的代碼實(shí)現(xiàn),感興趣的小伙伴可以去看完整代碼,文末有項(xiàng)目地址。

          Serive注解

          寫(xiě)這個(gè)注解主要是為了測(cè)試,本來(lái)要實(shí)現(xiàn)Component,一時(shí)半會(huì)沒(méi)想起來(lái)單詞如何拼寫(xiě),所以就選擇了service

          @Target(ElementType.TYPE)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Service {
              String value() default "";
          }

          注解的內(nèi)容和前面的都差不多,很簡(jiǎn)單,就是加了個(gè)targetRetention,然后把這個(gè)類(lèi)加在我們的service上即可:

          @Service
          public class TestService {

              public void helloIoc(String name) {
                  System.out.println("hello ioc, " + name);
              }
          }

          優(yōu)化包掃描器

          之前的包掃描器只能掃描一層目錄,這樣每層都指定包名就很繁瑣,所以我把它簡(jiǎn)單優(yōu)化了下,這樣只用輸入根包名,就可以實(shí)現(xiàn)整包掃描。

          這里用到了遞歸,當(dāng)路徑是文件夾時(shí),就會(huì)再次調(diào)用自己。

           private static void scanPackageToIoc(String packageName, Set<Class> classSet)
                      throws IOException, ClassNotFoundException 
          {
                  logger.info("start to scanPackage, packageName = {}", packageName);
                  Enumeration<URL> classes = ClassLoader.getSystemResources(packageName.replace('.''/'));
                  while (classes.hasMoreElements()) {
                      URL url = classes.nextElement();
                      File packagePath = new File(url.getPath());
                      if (packagePath.isDirectory()) {
                          File[] files = packagePath.listFiles();
                          for (File file : files) {
                              String fileName = file.getName();
                              if (file.isDirectory()) {
                                  String newPackageName = String.format("%s.%s", packageName, fileName);
                                  scanPackageToIoc(newPackageName, classSet);
                              } else {
                                  String className = fileName.substring(0, fileName.lastIndexOf('.'));
                                  String fullClassName = String.format("%s.%s", packageName, className);
                                  classSet.add(Class.forName(fullClassName));
                              }
                          }
                      } else {
                          String className = url.getPath().substring(0, url.getPath().lastIndexOf('.'));
                          String fullClassName = String.format("%s.%s", packageName, className);
                          classSet.add(Class.forName(fullClassName));
                      }
                  }
                  logger.info("scanPackage end, classSet = {}", classSet);
              }

          測(cè)試

          我們指定個(gè)包路徑測(cè)試下,順便測(cè)試下通過(guò)Ioc拿到對(duì)象,實(shí)現(xiàn)方法調(diào)用:

          scanPackageToIoc("io.github.syske.boot", classSet);
          logger.info("classSet = {}", classSet);
          scanRequestMapping(classSet);
          logger.info("requestMappingMap = {}", requestMappingMap);
          initSyskeBootContent(classSet);
          logger.info("contentMap = {}", contentMap);
          Object o = contentMap.get("io.github.syske.boot.service.TestService");
          if (o instanceof TestService) {
              ((TestService)o).helloIoc("云中志");
          }

          包掃描完后,生成一個(gè)classset集合;

          通過(guò)scanRequestMapping方法從class集合中拿出controller的類(lèi),并生成requestMapping和方法的集合;

          通過(guò)initSyskeBootContent方法從class集合中拿出service的類(lèi),并創(chuàng)建實(shí)例,放進(jìn)contentMap,這樣在你需要實(shí)例的時(shí)候,直接通過(guò)全類(lèi)名(包名 + 類(lèi)名)就可以拿到,然后執(zhí)行你想要執(zhí)行的方法即可。

          看下效果:

          883  [main] INFO  i.g.s.b.h.SyskeBootContentScanHandler - scanRequestMapping end, requestMappingMap = {/sayHello2=public java.lang.String io.github.syske.boot.controller.TestController.test(java.lang.String,java.lang.String), /sayHello=public java.lang.String io.github.syske.boot.controller.TestController.testName(java.lang.String), /test2=public java.lang.String io.github.syske.boot.controller.Test2Controller.test2(), /test=public java.lang.String io.github.syske.boot.controller.TestController.testRequstMapping()} 
          883  [main] INFO  i.g.s.b.h.SyskeBootContentScanHandler - requestMappingMap = {/sayHello2=public java.lang.String io.github.syske.boot.controller.TestController.test(java.lang.String,java.lang.String), /sayHello=public java.lang.String io.github.syske.boot.controller.TestController.testName(java.lang.String), /test2=public java.lang.String io.github.syske.boot.controller.Test2Controller.test2(), /test=public java.lang.String io.github.syske.boot.controller.TestController.testRequstMapping()} 
          899  [main] INFO  i.g.s.b.h.SyskeBootContentScanHandler - contentMap = {io.github.syske.boot.service.TestService=io.github.syske.boot.service.TestService@2812cbfa} 
          hello ioc, 云中志

          方法完美被執(zhí)行,想法實(shí)現(xiàn),打完收工。

          總結(jié)

          又是看起來(lái)復(fù)雜、寫(xiě)起來(lái)不難的一次需求,但是通過(guò)這樣的方式,能讓你更深入的理解springioc原理,當(dāng)然原理可能會(huì)有差異,但是也大同小異,再退一步來(lái)說(shuō),就算不一樣,面試的時(shí)候,面試官問(wèn)你懂不懂Ioc底層原理,你也可以大膽地我自己做過(guò)類(lèi)似于Ioc東西,這一點(diǎn)就很牛皮了。

          最近內(nèi)卷這個(gè)詞特別火,所有的平臺(tái)都在討論,但是IT這個(gè)行業(yè)不早都在內(nèi)卷了嗎?面試造火箭,進(jìn)門(mén)擰螺絲,太卷了。

          前幾天看到一個(gè)段子,說(shuō)是一個(gè)公司招司機(jī),面試官問(wèn)司機(jī),你知道汽車(chē)的啟動(dòng)過(guò)程嗎?能大概說(shuō)一下嗎?然后司機(jī)巴拉巴拉說(shuō)了一大堆:

          段子原文地址,有興趣的小伙伴自己去看:

          https://blog.csdn.net/dfskhgalshgkajghljgh/article/details/106457745


          下面是項(xiàng)目的開(kāi)源倉(cāng)庫(kù),有興趣的小伙伴可以去看看,如果有想法的小伙伴,我真心推薦你自己動(dòng)個(gè)手,自己寫(xiě)一下,真的感覺(jué)不錯(cuò):

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


          瀏覽 43
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操美女逼网站 | 久久天堂网 | 日本一级一片免费播放 | MFYD-013 肉食人妻女上司が部下を誘惑し | 性无码一区二区三区无码免费 |