項目應用小趣味(一):實體對象(bean)如何在各個類中加載

1,問題描述:

日前項目同事遇到一個小問題,來找我討論。他突然要寫一個工具類,專門解決數據庫的統計和字段監控問題。它不在原來體系中,還需要加載各種實體對象,對數據進行統計。

public class MPOperationUtil{
    /**
    **根據輸入次數,數據庫統計數據數值增加1,5以內,返回錯誤標識XXXX,超過返回錯誤標YYYY。
    **/
    public static String increaseErrorCode(...){
         //庫表Cust的實體對象:最新更新時間的一條客戶信息
         CustInfoRepostiory cus
         CustInfo cust = cus.findMaxUpdTime(custInfo);
         //cus.findMaxUpdTime(custInfo) 出異常NullPointExcepiton
         .......
         //操作數據庫
         cus.update(cust);
         return errorCode;
    }
    public static void resetErrorCode(String errorCode){
         CustInfo custInfo;
         custInfo.setErrorCode(errorCode);
         custInfo.update(custInfo);//毫無疑問,也是報錯。
    }
}

先是想看項目中是否有類似的解決方案,沒有。他自己也是試了幾個做法,可是拿不到值。
最後我給了一個解決思路(外部傳值),簡單明瞭的解決。

2,問題分析和解決

  • 解決小思路一:spring注入
    框架原有的注入
public abstract class BaseAction
    /**
       *通過指定類型從IOC容器中查找bean
     /
     protected <T> T get(Class<T> beanType){
         return applicationContext.getBean(beanType);
     }

對方想的是應用原有代碼中類似例子

public static String increaseErrorCode(...){
         ....
         CustInfo cust = get(CustInfoRepostiory.class).findMaxUpdTime(custInfo);
         //照樣出異常NullPointExcepiton:工具類並沒有加入bean體系
         .......
         //
         return errorCode;
    }
    或者
    @Autowired
    private CustinfoRepostiory c;//拿不到。 

修改方案:因爲MPOperationUtil沒有納入管理。那麼在xxx-services.xml或xxx-util.xml中加入MPOperationUtil對象

1,process(業務交易或單元,包含Action,一對多)上層處理裏視情況加入MPOperationUtil
//Action業務原子操作,流程處理。通過operation定義,採用Java反射技術實現方法的定義
2,<action id="mpOperationUtil" calss="com.XXXX.bbip.jpts.utils.MPOperationUtil"/>
3,public class MPOperationUtil extends BaseAction{
         CustInfo cust = get(CustInfoRepostiory.class).
             findMaxUpdTime(custInfo);//OK
}
次方案功能上是實現了,但是Java的基本設計思想被破壞。此情此景,通過xml配置實現不是好辦法。
  • 解決思路二:直接new對象
    這個看視乎可以,直接new出可用的具體實體對象。還有其他情況下,可能破壞了工廠模式,阻礙了擴展性。此工具只服務一個Action。
    //直接通過接口,new具體的實體對象
    CustInfoRepostiory custInfoRepostiory =(CustInfoRepostiory)new CustInfo(); 
    CustInfo cust = custInfoRepostiory.findMaxUpdTime(custInfo);
         //可以
         .......
         custInfoRepostiory.update(cust);
         //由於是重新創建了一個對象,此對象沒有納入事務管理(相對於單獨行動,裸奔),
         //它對數據庫的操作是單獨的,存在隱藏風險。
         return errorCode;
  • 解決思路三:外部傳參數
    把外部實體bean傳入,進行操作。相當於引用的思想。
1,外部需要使用的Action,肯定是拿到Context內容的。
   public class XXXAction extends BaseAction{
         String errorCode=null;
         errorCode = MPOperationUtil.increaseErrorCode(
         custInfoEntity,get(CustInfoRepository.class));
        //把get(CustInfoRepository.class)當參數傳入工具類的方法中
   }
2public class MPOperationUtil{
        public static String increaseErrorCode(
         CustInfo custInfoEntity,CustInfoRepository custInfoRepository){
             ....
             cust=custInfoRepository.findMaxUpdTime(CustInfoEntity);
             custInfoRepository.update(cust);//少改動,高實現
        }
   }

這個做法很簡單,也很普遍。有時候編程容易陷入困局,自己都沒發現,別人來點一下就通了 。

最後的總結:在諸多方法中比較。
spring注入:可行,但是會打亂原來的xml配置,尤其是在大項目中,對突然的加代碼或配置,有一定的風險。
發射機制:可行,但是項目中沒有使用,明顯的反射機制去拿bean。
外部傳值:可行,在工具類的方法中,把需要的bean實體傳入進來,構造傳值也是同理。
用New創建:不可行,new一個實體對象是可以拿到實體,但是拿不到對象類的上下文內容(context)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章