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

          小心Lombok用法中的坑

          共 2457字,需瀏覽 5分鐘

           ·

          2021-12-26 00:00

          剛才寫完了代碼,自測的時候,出現(xiàn)了NPE問題。

          排查的時候發(fā)現(xiàn)是Lombok的坑,以前也遇到過,所以覺得有必要過來記錄一下。

          我先描述一下現(xiàn)象,我的代碼里面訂單服務(wù)A 需要調(diào)用緩存服務(wù)B,服務(wù)B就是一個Bean,使用方式是這樣的:

          class?ServiceA?{
          ??//使用?Lombok?提供的setter
          ??@Setter
          ??private?ServiceB?bXCacheService;
          ??
          ??public?Data?getData()?{
          ?????//這里出現(xiàn)了NPE問題
          ?????bXCacheService.getSomeThing();
          ??}?
          }

          這個問題使用Lombok 的同學(xué)可能有人遇到過,我用的是螞蟻的Sofa,Spring也是類似的,

          先說下bean初始化過程,是通過反射,調(diào)用set 方法初始化bean,下面代碼是我截取的部分代碼:Spring 中的初始化bean方法

          public?void?setValue(final?Object?object,?Object?valueToApply)?throws?Exception?{
          ???//獲取write方法,實際就是setXXX方法
          ????final?Method?writeMethod?=?this.pd.getWriteMethod();
          ????if?(!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())?&&?!writeMethod.isAccessible())?{
          ????????if?(System.getSecurityManager()?!=?null)?{
          ????????????AccessController.doPrivileged(new?PrivilegedAction()?{
          ????????????????@Override
          ????????????????public?Object?run()?{
          ????????????????????writeMethod.setAccessible(true);
          ????????????????????return?null;
          ????????????????}
          ????????????});
          ????????}?else?{
          ????????????writeMethod.setAccessible(true);
          ????????}
          ????}
          ????final?Object?value?=?valueToApply;
          ????if?(System.getSecurityManager()?!=?null)?{
          ????}?else?{
          ????????//?通過反射?用set?方法注入屬性
          ????????writeMethod.invoke(getWrappedInstance(),?value);
          ????}
          }

          問題就出在 Sofa 拼接 bean 變量 set 方法的方式,例如:如果我們希望初始化的 bean 名稱為 cacheService,那么 Sofa 拼接的 set 方法為 setCacheService,也就是set + 變量(首字母大寫+剩余字符)。

          但是如果 bean 名稱是:tCacheService,bean 首字母小寫,第二次字符是大寫,那 set 方法就變成了:settCacheService,當(dāng)?shù)诙€字符是大寫的時候,set 不會設(shè)置變量 t 為大寫 T。

          但是 Lombok 不是這樣,Lombok 的setter注解實現(xiàn)機制,會讓 tCacheService 的 setter 方法變成 setTCacheService(), 所以bean初始化的時候會找不到 WriteMethod,bean注入失敗,報NPE問題。

          解決方法

          解決方法要么調(diào)整bean的命名方式,不要讓第二個字符是大寫,要么改變這種變量不使用Lombok 注入,使用Idea / Eclipse 生成的setter 方法。

          也算是Lombok 和 Idea 生成 setter 方法的區(qū)別,一般框架、中間件更偏向 Idea 的這種set 變量方式。

          另一個需要注意的問題

          還有一個不只是Lombok 要注意的點,就是boolean 類型的變量嚴(yán)禁使用 is 開頭,因為無論是Lombok 還是Idea 默認(rèn)生成的get 方法都是is打頭,丟掉多余的is,set方法去掉is,可能引發(fā)非預(yù)期的問題,例如變量 boolean isOpen 和 變量 boolean open 變量的get方法名是一樣的:isOpen(); set 方法都是 setOpen(boolean isOpen);

          private?boolean?isOpen;

          public?boolean?isOpen()?{
          ??return?isOpen;
          }

          public?void?setOpen(boolean?open)?{
          ??isOpen?=?open;
          }

          常規(guī)編程規(guī)范里面會讓返回值是 boolean 變量的方法名以 is開頭,但是變量本身不帶is。

          //?開火開關(guān)??--?集中參數(shù)中心配置項
          private?String?fireSwitch;?

          public?boolean?isOpenFire()?{
          ???return?StringUtils.equalsIgnoreCase(?"TRUE",?fireSwitch);
          }

          往期推薦

          Java中List排序的3種方法!


          面試官:元素排序Comparable和Comparator有什么區(qū)別?


          面試官:HashSet是如何保證元素不重復(fù)的?


          瀏覽 34
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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无码专区在线 |