<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用法中的坑

          共 4175字,需瀏覽 9分鐘

           ·

          2021-08-29 08:39

          剛才寫完了代碼,自測的時候,出現了NPE問題。

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

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

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

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

          先說下bean初始化過程,是通過反射,調用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<Object>() {
                          @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,當第二個字符是大寫的時候,set 不會設置變量 t 為大寫 T。

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

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

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

          還有一個不只是Lombok 要注意的點,就是boolean 類型的變量嚴禁使用 is 開頭,因為無論是Lombok 還是Idea 默認生成的get 方法都是is打頭,丟掉多余的is,set方法去掉is,可能引發(fā)非預期的問題,例如變量 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。

          // 開火開關  -- 集中參數中心配置項
          private String fireSwitch; 

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

          1. 你真的會寫for循環(huán)嗎?來看看這些常見的for循環(huán)優(yōu)化方式

          2. SpringCloud常見面試題(2021最新版)

          3. 神奇的 SQL 之別樣的寫法 → 行行比較

          4. 華為OD(外包)社招技術二面,總結復盤

          最近面試BAT,整理一份面試資料Java面試BATJ通關手冊,覆蓋了Java核心技術、JVM、Java并發(fā)、SSM、微服務、數據庫、數據結構等等。

          獲取方式:點“在看”,關注公眾號并回復 Java 領取,更多內容陸續(xù)奉上。

          文章有幫助的話,在看,轉發(fā)吧。

          謝謝支持喲 (*^__^*)

          瀏覽 111
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  中文字幕A片无码免费看 | 快一本码道在线播放视频国产 | 久久久久久欧美二区电影网 | 欧美内射视频播放 | 九一精品在线看 |