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

          手寫web服務(wù)器:定義Configuration和Bean注解,實(shí)現(xiàn)更靈活的類注入

          共 6456字,需瀏覽 13分鐘

           ·

          2021-06-12 06:33

          前言

          前幾天,我們實(shí)現(xiàn)了Service注解,解決了類注入的問題(component注解后面實(shí)現(xiàn),這個(gè)就很簡單了),但是這種方式不夠靈活,比如我們要實(shí)現(xiàn)某些屬性的賦值,或者其他特殊的構(gòu)建方法,這些注解就不夠靈活了,為了解決這個(gè)問題,spring提供了Configuration注解和Bean注解,今天我們就參照這兩個(gè)注解的功用,用我自己的方式來實(shí)現(xiàn)這兩個(gè)注解,讓我們的類注入更靈活。

          話不多說,直接開始。

          實(shí)現(xiàn)過程

          定義注解

          configuration注解,我們從一開始就在寫注解,所以到現(xiàn)在都是閉著眼睛寫的,so easy!

          @Target(ElementType.TYPE)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Configuration {
          }

          Bean注解

          @Target(ElementType.METHOD)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Bean {
          }

          核心實(shí)現(xiàn)

          我們說的核心實(shí)現(xiàn),主要是指這兩個(gè)注解的使用,因?yàn)?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);">Bean注解的作用是創(chuàng)建對象,所以必須在服務(wù)器啟動前完成創(chuàng)建,但是不能早于包掃描前,我們要在包掃描完成后進(jìn)行:

          // 掃描包
          componentScanInit(aClass);
          // 初始化配置類
          initConfiguration();

          我們看下配置類初始化里面是如何實(shí)現(xiàn)的:

           /**
               * 初始化配置類
               */

          private static void initConfiguration() {
              classSet.forEach(c -> {
                  try {
                      if (hasAnnotation(c, Configuration.class)) {
                          Method[] methods = c.getMethods();
                          Object o = c.newInstance();
                          for (Method method : methods) {
                              Bean annotation = method.getAnnotation(Bean.class);
                              if (Objects.nonNull(annotation)) {
                                  Object invoke = method.invoke(o);
                                  contentMap.put(method.getReturnType().getName(), invoke);
                              }
                          }
                      }
                  } catch (Exception e) {
                      logger.error("掃描配置類錯誤", e);
                  }
              });
          }

          這里也很簡單,就是循環(huán)遍歷我們的包掃描結(jié)果,拿出有Configuration注解的類,然后找到有Bean注解的方法,運(yùn)行方法,把方法運(yùn)行結(jié)果放進(jìn)我們的Ioc容器即可。

          簡單應(yīng)用

          我們有這樣一個(gè)類,我們需要通過BeanConfiguration注解來實(shí)現(xiàn)更靈活的類注入

          public class TestBean {
              private String name;
              private int age;

              public TestBean() {
              }

              public TestBean(String name) {
                  System.out.println("create bean, " + name);
              }
              public void testBean() {
                  System.out.println(this);
                  System.out.println("hello bean");
              }

              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  this.name = name;
              }

              public int getAge() {
                  return age;
              }

              public void setAge(int age) {
                  this.age = age;
              }
              @Override
              public String toString() {
                  return "TestBean{" +
                          "name='" + name + '\'' +
                          ", age=" + age +
                          '}';
              }
          }

          我們的配置類:

          @Configuration
          public class TestConfig {
              @Bean
              public TestBean testBean() {
                  TestBean testBean = new TestBean();
                  testBean.setAge(18);
                  testBean.setName("云中志");
                  return testBean;
              }
          }

          測試

          我們在Controller中注入testBean:

          @Controller
          public class Test2Controller {

              @Autowired
              private TestService service;

              @Autowired
              private TestBean testBean;

              @RequestMapping("/testAutowire")
              public String testAutowire(@RequestParameter("name") String name){
                  testBean.testBean();
                  return service.helloIoc(name);
              }
          }

          然后,我們前端訪問下看下效果:

          配置類中的屬性也已經(jīng)被注入進(jìn)來了,這種方式的好處就是比較靈活,你可以根據(jù)自己的需要調(diào)用對應(yīng)的方法,實(shí)現(xiàn)符合你需求的構(gòu)建方式,是不是很簡單呀!

          總結(jié)

          今天的內(nèi)容總體來說還是比較簡單的,核心的點(diǎn)就是注解的解析和方法的反射調(diào)用,當(dāng)然難點(diǎn)也是有的,你要在實(shí)現(xiàn)之前考慮好思路,因?yàn)榇a本身只是思路的表達(dá),所以在我的認(rèn)知理解中,我覺得合格的軟件工程師,首先得是個(gè)合格的架構(gòu)師和設(shè)計(jì)師,否則你真的是能當(dāng)個(gè)小碼農(nóng)了,遇到需求的時(shí)候,先想想如果讓你來做,你會如何實(shí)現(xiàn),而不是考慮該不該你來做,每一次你排斥的事情,其實(shí)對你而言,都是一次機(jī)會,重要的是你如何看待它。

          好了,今天的內(nèi)容就到這里吧。

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

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


          瀏覽 29
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  AV中文在线观看 | 成人精品一区二三区 | 成人免费观看视频亚洲 | 思思精品热视频 | 欧美在线三级网 |