hibernate validate工具,小心你的姿勢不對

系統運營後臺有個導入線下交易的功能。產品和運營反饋,當excel數據量超過8千條時,會變得超級慢,動輒要等三四十秒。

哎!這麼慢,擱誰能不鬧心呢?

基於此,這兩天,我覺得優化一下,可是,一來二去,從昨天週一到現在眼看兩天了,對代碼進行各種排查和調整,還是沒有達到理想的效果————至少,別讓用戶傻傻等待超過5秒吧,最次也不能超過10秒吧。

這兩天特殊時期,公司的保潔阿姨應該也陽了,始終沒來上班。那麼,衛生工作就得我們上班族自理了。

 

 

我四下張望一下,兩個垃圾桶都滿了。再看小夥伴們都在安靜的碼代碼。我就收拾一下吧。在提着垃圾袋扔垃圾的路上,突然靈光乍現。是不是數據校驗那塊導致的呢?————校驗用的是Hibernate的validation-api。

完事回到工位,趕緊試試。

————峯迴路轉。

果然,本地測試才驚人地發現,用Hibernate的校驗工具,8200條數據耗時47s,而直接用apache common的util類校驗,僅需1~2s。

why?

why?

why?

程序使用不當所致。先貼出來關鍵代碼:

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

public class ValidationUtil {

    private ValidationUtil() {
    }

    /**
     * 根據註解,校驗參數的工具類
     *
     * @pojo pojo bean
     * @return 驗證結果
     */
    public static Result<Void> validate(Object pojo) {

        if (pojo == null) {
            return Result.err(ResultCodeEnum.ERROR_PARAM, "參數爲空");
        }

        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(pojo);
        if (CollUtil.isNotEmpty(constraintViolations)) {
            return Result.err(ResultCodeEnum.ERROR_PARAM, constraintViolations.iterator().next().getMessage());
        }
        return Result.success();
    }
}

 

當針對爲數不多的對象來校驗,發現不出來性能問題。但是,當達到上面的8000多條數據時,那性能可以差太多了。

細看控制檯打印出來的log,可見一斑。

 

 

問題出在 validatorFactory 和 validator 這兩個局部對象的初始化上。尤其是初始化 validatorFactory調用Validation#buildDefaultValidatorFactory, 這個方法內部會涉及到xml文件的讀取和類映射,可見,每次都做這個事情,CPU表示很無辜!

 

問題即答案————>優化方案是將這2個對象的初始化放在類初始化時。

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