Spring AOP汎用入参検査の最終版

4971 ワード

入试検査はずっとプログラムの中で一つの鶏の肋骨で、食事の味はまた食べなければなりません.いくつかのバージョンの変更を経て、今回のプロジェクトはオンラインになりました.
基調:hibernate.validator
実現-低配合版
1、pomの導入


    org.hibernate

    hibernate-validator

    5.0.2.Final

2、パッケージ検査クラス
public class ValidationUtils {
    private static ILog logger = LogFactory.getLogger(ValidationUtils.class);

    /**
     *   hibernate        
     */
    private static Validator validator = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();

    public static  void validate(T obj) {
        Set> constraintViolations = validator.validate(obj);
        //       
        if (constraintViolations.size() > 0) {
            logger.warn("param invalidate fail :{}", constraintViolations.iterator().next().getMessage());
            System.out.println(constraintViolations.iterator().next().getMessage());
        }
    }

}
3、応用
TradeDtoをチェックするとTradeDtoで必ず送信されるパラメータに@NotNull注を追加し、msgに戻ると定義します.
public class TradeDto {
    @NotNull(message = "  ID  ")
    private Long orderId;

    @NotNull(message = "   ID  ")
    private Long businessId;
.......
}
方法においては、元の判断によりパッケージ検査を呼び出すように変更されました. 
    public Result createTrade(TradeDto tradeDto) {
        if (tradeDto == null || tradeDto.getOrderId() == null || tradeDto.getBusinessId() == null) {
            return ResultWrapper.fail(ErrorCode.PARAMETER_CANNOT_NULL);
        }
   :

    ValidationUtils.validate(tradeDto);
4、結果
参tradDtoのordeldが空の場合、「注文IDが空」のmsgに戻ります.
************************************************ 方案が完了したら、******************************************************************************************************************************************************************が発生します.
このまま終わったらあまりにlowです.
方案の一欠点:
1、参加検査のたびに、Validation Utilsを書きます.
2、Validation Utilsパッケージ類は単一dtoのみを検査しますが、Long+Dtoなどの組み合わせがある場合は?もしかしてValidationUtilsを二回調べればいいですか?(乱暴で下品)
3、validate方法はvoidに戻りますが、それはその後実行しますか?それともreturnですか?(戻り値は業務ロジックと組み合わせるべき)
を選択します
基調:AOP+コメント;メソッド可変パラメータ;リターンパッケージ
1、注解類のパッケージ
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Valid {
}
2、切麺類のパッケージ
@Aspect
@Component
@Order(2)
public class ValidAspect {
    /**
     *           
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.trade.component..*.*(..)) && @annotation(com.trade.aspect.Valid))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Result validate = ValidationUtils.validate(args);
        if (validate.isSuccess()) {
            return joinPoint.proceed();
        }
        return validate;
    }
}
注:注解order(1)後に説明します.
3、検査方法の最適化(可変パラメータ+業務の意味ある戻り値)
    public static  Result validate(T... obj) {
        for (int i = 0; i < obj.length; i++) {
            if (obj[i] == null) {
                return ResultWrapper.fail(ErrorCode.PARAMETER_IS_NULL);
            }
            Set> constraintViolations = validator.validate(obj[i]);
            if (constraintViolations.size() <= 0) {
                continue;
            } else {
                logger.warn("param invalidate fail :{}", constraintViolations.iterator().next().getMessage());
                System.out.println(constraintViolations.iterator().next().getMessage());
                return ResultWrapper.fail(constraintViolations.iterator().next().getMessage());
            }
        }
        return ResultWrapper.success();
    }
4、応用
    @Valid
    @Log
    @Override
    public Result createTrade(TradeDto tradeDto) {..}
5、結果
@Validコメントの実行方法を追加して、パラメータタイプは複数(ベースタイプ+Dtoコンビネーション参照)をサポートします.
AOP実行順序制御
前のブログでAOPを使ってログを入力しましたが、createTradeのように、この二つのzindiカスタムAOPがgaifに機能しています.AOPの実行順序はどうやって制御しますか?@Order(int)注解はこの役割です.int値が小さいほどyuexを先に実行します.したがって、Logカットポイントxianプロジェクトは@Order(1)を適用して、まず入力印刷を行い、その後、パラメータチェック@Validを実行します.具体的な他の制御方法は以下のようにまとめられています.
1、@Order(最も直感的で簡単)
2、書類を配置する(一部の面接官が根掘り葉掘りをしないでください.分かります.)
  
        
            
            
            
  
3、表示実現Orderインターフェース
@Component
@Aspect
public class MessageQueueAopAspect1 implements Ordered{
    @Override
	public int getOrder() {
		return 2;
	}
	
}