Cet article introduit l'écriture d'un AOP basé sur Spring Boot et JDK8, combinant des annotations personnalisées pour obtenir une vérification courante des paramètres d'interface.
raison
Actuellement, la méthode de vérification de paramètres couramment utilisée consiste à ajouter des annotations sur la classe d'entité, mais pour différentes méthodes, les règles de vérification appliquées sont également différentes. Par exemple, il y a une entité Accountvo:
classe publique Accountvo {nom de chaîne privée; // Nommez l'âge entier privé; // Âge}Supposons qu'il y ait une entreprise: lorsqu'un utilisateur s'inscrit, il ou elle doit remplir son nom, et lorsqu'un utilisateur se connecte, il ou elle n'a qu'à remplir son nom. Ensuite, il est évidemment inapproprié d'ajouter des règles de vérification aux classes d'entités.
Par conséquent, j'ai toujours voulu implémenter une vérification de paramètre au niveau de la méthode. Différentes méthodes peuvent appliquer des règles de vérification différentes pour les mêmes paramètres d'entité, qui ont donné naissance à cet outil et ont été utilisés dans le travail quotidien depuis longtemps.
introduire
Jetons un coup d'œil à l'utiliser en premier:
@ServicePublic Class TesImplt implémente iTestService {@Override @Check ({"Name", "Age"}) public void testValid (accountvo vo) {// ...}}L'annotation @Check sur la méthode indique que le nom et les propriétés d'âge dans le paramètre Accountvo ne peuvent pas être vides. En plus de la vérification non vide, il prend également en charge le jugement de taille et la vérification de l'égalité:
@Check ({"id> = 8", "name! = Aaa", "title <10"})Le message d'erreur par défaut renvoie les champs, les causes d'erreur et les méthodes appelées, telles que:
UpdateUserid ne doit pas null lors de l'appel TestValidId doit> = 8 lors de l'appel TestValidName MUST! = AAA lors de l'appel TestValid
Les informations de retour d'erreur personnalisées sont également prises en charge:
@Check ({"Title <= 8: Le nombre de caractères de titre ne dépasse pas 8 caractères, y compris les marques de ponctuation"}) public void testvalid (testpo po) {// ...}Ajoutez simplement: après la règle de vérification et écrivez des informations personnalisées, qui remplaceront le message d'erreur par défaut.
PS: Le principe central est d'obtenir la valeur du champ dans l'entité du paramètre par réflexion, puis de le vérifier en fonction des règles. Par conséquent, seules les méthodes contenant un paramètre sont prises en charge et les paramètres ne peuvent pas être du type de base.
utiliser
Comment utiliser AOP dans Spring-Boot, je ne vais pas entrer dans les détails ici et introduire principalement le code central dans AOP.
Dépendances Maven
En plus des dépendances de Spring-Boot, les dépendances tierces requises ne sont pas des dépendances de base, et vous pouvez choisir en fonction de vos habitudes personnelles:
<! - Pour la vérification des chaînes -> <dependency> <proupId> org.apache.commons </proncId> <Artifactid> Commons-Lang3 </ Artifactid> <DERSE> 3.3.2 </ version> </ Dependency> <! - Pour Log Impression -> <Dedency> <ProupID> ORG.SLF4J <version> 1.7.25 </ version> </Dependance>
Annotations personnalisées
Importer java.lang.annotation.elementType; import java.lang.annotation.retention; import java.lang.annotation.target; import static java.lang.annotation.retentionpolicy.runtime; / ** * Annotation de vérification des paramètres * créée par Cipher le 2017/9/20. * / @ Target ({elementType.type, elementType.Method}) @ Rétention (Runtime) public @Interface Check {// Règles de vérification de champ, format: nom de champ + règles de vérification + Message d'erreur Colon +, par exemple: id <10: Id doit être inférieur à 10 chaîne [] valeur ();}Code de base
En interceptant la méthode d'interface avec l'annotation @Check, effectuez une vérification des paramètres avant l'exécution de la méthode. S'il y a un message d'erreur, il sera renvoyé directement:
@Around (value = "@ com.cipher.checker.check") // Ici, vous devez passer au chemin du chemin de vérification d'objet public d'annotation personnalisée (ProcedingJoinpoint Point) lève Throwsable {Object Obj; // String de vérification du paramètre msg = docheck (point); if (! StringUtils.Isempty (msg)) {// Vous pouvez retourner la classe de retour encapsulée Throw New illégalArgumentException (msg); } obj = point.proceed (); retour obj;}La méthode de vérification de base dans la méthode DOCKECK, le principe principal est d'obtenir le nom de champ et les règles de vérification spécifiées sur l'annotation, d'obtenir la valeur du champ correspondant dans l'entité du paramètre par réflexion, puis d'effectuer une vérification:
/ ** * Vérification des paramètres * * @param point ProcedingJoinpoint * @return Message d'erreur * / private String doCheck (ProcedingJoinpoint Point) {// Get Method Paramet Value Object [] arguments = Point.getArgs (); // Obtenir la méthode méthode Méthode = getMethod (point); String MethodInfo = StringUtils.iSempty (méthode.getName ())? "": "En appelant" + méthode.getName (); String msg = ""; if (isCheck (méthode, arguments)) {check annotation = method.getAnnotation (check.class); String [] fields = annotation.value (); Objet vo = arguments [0]; if (vo == null) {msg = "param ne peut pas être nul"; } else {for (String Field: Fields) {// Analyse Field FieldInfo info = RESOLOLFIELD (Field, MethodInfo); // Obtenez la valeur de la valeur de l'objet de champ = ReflectionUtil.invokeGetter (VO, info.field); // Exécuter la règle de vérification booléen isvalid = info.optenum.fun.apply (valeur, info.operatornum); msg = isvalid? MSG: info.innermsg; }}} return msg;}Vous pouvez voir que la logique principale est:
Fields d'analyse -> Obtenez la valeur des champs -> Exécuter les règles de vérification
Une classe d'énumération est maintenue en interne et les opérations de vérification pertinentes y sont spécifiées:
/ ** * Opération Enum * / Enum Operator {/ ** * supérieur à * / Greater_Than (">", CheckParamaspect :: isGreaterthan), / ** * supérieur à ou égal à * / Greater_Than_equal ("> =", CheckParamaspect :: isGreaterThanequal), / ** * moins que * / moins / ** * Moins ou égal à * / boins_than_equal ("<=", checkParamaspect :: ISlessThanequal), / ** * pas égal à * / not_equal ("! =", CheckParamaspect :: isNotequal), / ** * non vide * / not_null ("not null", checkParamaspect :: Isnotnull); valeur de chaîne privée; bifonction privée <objet, chaîne, booléen> amusant; Operator (String Value, Bifonction <Object, String, boolean> fun) {this.value = value; this.fun = fun; }} Pour des raisons d'espace, je n'élargirai pas tous les codes un par un. Les amis intéressés peuvent obtenir tous les codes source à l'adresse suivante: Ciphermagic / Java-Learn / Sandbox / Checker
FAIRE
enfin
Merci pour votre lecture. Des amis qui l'aiment peuvent l'aimer sur Github. Si vous avez des questions ou des suggestions, veuillez laisser un message ci-dessous et attendez avec impatience votre réponse.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.