Java自定义注解进行参数校验

您所在的位置:网站首页 spi检查参数是怎么定义的 Java自定义注解进行参数校验

Java自定义注解进行参数校验

2023-09-05 19:27| 来源: 网络整理| 查看: 265

Java自定义注解 简介

​ Java自定义注解是通过运行时靠反射获取注解。

​ 常用于:登陆、权限拦截、日志处理,例如我们要获取某个方法的调用日志,可以通过AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志注解,就进行日志记录。

​ 注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效。

创建自定义注解

创建自定义注解与编写接口很相似,除了它的接口关键字前有个@符号,我们可以在注解中定义方法

package com.tao.annotations; import java.lang.annotation.*; @Documented @Target(ElementType.METHOD) @Inherited @Retention(RetentionPolicy.RUNTIME) public @interface MethodInfo{ String author() default "Pankaj"; String date(); int revision() default 1; String comments(); } 注解方法,没有参数可设定默认值返回类型仅限于原始类型:字符串、枚举、注解,或以上构成的数组可包含四种【元注解】与之绑定 Documented – 表示使用该注解的元素应被javadoc或类似工具文档化**Target --**表示支持注解的元素种类:可选【TYPE, METHOD, CONSTRUCTOR, FIELD】,不写则全部支持**Inherited --**注解类型会被自动继承**Retention --**接收RetentionPolicy参数,可选【SOURCE, CLASS, RUNTIME】,表示注解类型保留时间的长短 Java内置注解

Java提供3种内置注解 : @Override、@Deprecated、@SuppressWarnings

@Override : 表示正在覆盖SuperType的方法,该方法来自父类或接口

@Deprecated :表示该方法已被弃用,应在javadoc中提供信息,说明弃用原因以及替代方法

@SuppressWarnings:这个注解仅仅是告知编译器,忽略它们产生的特殊警告

示例如下:

package com.tao.annotations; import java.io.FileNotFoundException; import java.util.*; public class AnnotationExample { public static void main(String[] args) { } @Override @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1) public String toString() { return "Overriden toString method"; } @Deprecated @MethodInfo(comments = "deprecated method", date = "Nov 17 2012") public static void oldMethod() { System.out.println("old method, don't use it."); } /** * 在泛型中使用原始类型,会产生警告,但通过@SuppressWarnings可以抑制警告 */ @SuppressWarnings({ "unchecked", "deprecation" }) public static void genericsTest() throws FileNotFoundException { List l = new ArrayList(); l.add("abc"); oldMethod(); } } Java注解解析

我们将使用Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。

package com.tao.annotations; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class AnnotationParsing { public static void main(String[] args) { try { for (Method method : AnnotationParsing.class .getClassLoader() .loadClass(("com.tao.annotations.AnnotationExample")) .getMethods()) { // checks if MethodInfo annotation is present (before "链接-解释") if (method .isAnnotationPresent(com.tao.annotations.MethodInfo.class)) { try { // iterates all the annotations available in the method for (Annotation anno : method.getDeclaredAnnotations()) { System.out.println("Annotation in Method '" + method + "' : " + anno); } MethodInfo methodAnno = method .getAnnotation(MethodInfo.class); if (methodAnno.revision() == 1) { System.out.println("Method with revision no 1 = " + method); } } catch (Throwable ex) { ex.printStackTrace(); } } } } catch (SecurityException | ClassNotFoundException e) { e.printStackTrace(); } } } 项目实例

应用场景:验证手机号

package com.tao.annotations; import com.tao.IsPhoneValidHandler; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; /** * 验证手机号格式-注解 */ @Target({ElementType.METHOD,ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = {IsPhoneValidHandler.class}) public @interface Phone { String message() default "手机号格式不正确"; Class[] groups() default {}; Class[] payload() default {}; } package com.tao.handler; import com.tao.annotations.Phone; import org.springframework.util.StringUtils; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Pattern; /** * 验证手机号格式-校验规则 */ public class IsPhoneValidHandler implements ConstraintValidator { @Override public void initialize(Phone constraintAnnotation) { } @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 不验证空值 if (StringUtils.isEmpty(value)) { return true; } // 参数不是空,对 手机号格式进行校验 return isPhone(value); } /** 验证是否为手机号 */ public static boolean isPhone (String phone){ String pattern = "^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$"; if (Pattern.matches(pattern, phone)) { return true; }else{ return false; } } } 案例解析:

1、附加在自定义注解上的三个“元注解”:

目标:方法返回值、字段、注解、构造器、方法参数

持久类型:运行时

生成Javadoc文档

附加校验规则:@Constraint(validatedBy = {IsPhoneValidHandler.class}),使用自定义的校验规则,进行参数校验,校验规则类需要继承ConstraintValidator接口,实现initialize和isValid方法



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3