Java 自定义注解

像平时用到的 springboot、mybatis 等框架提供了许多的注解,免去了许多配置文件的繁琐工作,大大简便了开发,Java 提供了自定义注解的功能,这里就先展示简单的例子。

1、注解的作用
注解可以看作是一种特殊的标记,可以用在方法、类、参数和包上,程序在编译或者运行时可以检测到这些标记而进行一些特殊的处理,例如标注在方法上可以实现接口权限的校验。

使用场景:自定义注解+拦截器或者 AOP。

声明方式:通过关键字 @interface 声明为注解,例子如下:

@Target({ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ValidateUnionRepeat {
    /**
     * 异常信息
     */
    String msg() default "";

    /**
     * 需验证属性数组
     */
    String[] validateFields() default {};

    /**
     * 用于判断注解是否生效(默认true生效)
     */
    boolean effective() default true;
}

2、注解的元素类型
主要有@Target,@Retention,@Document,@Inherited 用来修饰注解。

2.1、@Target
表明该注解可以应用的java元素类型。

public enum ElementType {

  	//类,接口,枚举类
    TYPE, 

  	//成员变量,枚举常量
    FIELD, 

	//方法
    METHOD,

	//形式参数
    PARAMETER,

 	//构造方法
    CONSTRUCTOR,

	//局部变量
    LOCAL_VARIABLE,

    //注解
    ANNOTATION_TYPE,

    //包
    PACKAGE,

    //类型参数
    TYPE_PARAMETER,

    //类型使用
    TYPE_USE
}

2.2、@Retention
表明该注解的生命周期。

public enum RetentionPolicy {
   
   	//源文件保留
    SOURCE,

  	//编译期保留,默认值
    CLASS,

  	//运行期保留,可通过反射去获取注解信息
    RUNTIME
    
}

取值 描述 作用范围 使用场景

取值描述作用范围使用场景
RetentionPolicy.SOURCE表示注解只保留在源文件,当java文件编译成class文件,就会消失源文件只是做一些检查性的操作,,比如 @Override 和 @SuppressWarnings
RetentionPolicy.CLASS注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期class文件(默认)要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife)
RetentionPolicy.RUNTIME注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在运行时也存在需要在运行时去动态获取注解信息

2.3 @Documented

表明该注解标记的元素可以被Javadoc 或类似的工具文档化。

2.4、@Inherited
表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解

举例

/**
 * 多字段联合验证(加于类上)
 *
 */
@Target({ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ValidateUnionRepeat {
    /**
     * 异常信息
     */
    String msg() default "";

    /**
     * 需验证属性数组
     */
    String[] validateFields() default {};

    /**
     * 用于判断注解是否生效(默认true生效)
     */
    boolean effective() default true;
}
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public RespMsg<?> add(@RequestBody @Valid MonDeptConfigForm monDeptConfigForm) {
        CheckOnlyUtil.checkOnlyFuncForInsert(monDeptConfigForm, monDeptConfigService, MonDeptConfigDto.class, null);
        try {
            return RespMsg.success();
        } catch (Exception e) {
            throw new CdtBaseException(e.getMessage(), e);
        }
    }
  private static void validateClass(Class<?> beanClass, Object formBean,
                                      Class dtoClass, IBaseService baseService, String[] idFields, Object[] ids) throws Exception {
        //查询条件Dto对象
        Object dtoBean = null;
        //查询条件form对象
        Object formBeanParam = null;
        boolean result = false;
        String repeatMsg = "";
        long num = 0;
        boolean isNull = false;
        //判断是否关联属性重复限制
        if (beanClass.isAnnotationPresent(ValidateUnionRepeat.class)) {
            ValidateUnionRepeat unionRepeat = beanClass.getAnnotation(ValidateUnionRepeat.class);
            if (!unionRepeat.effective()) {
                return;
            }
            String[] validateFields = unionRepeat.validateFields();
            if (ArrayUtils.isEmpty(validateFields)) {
                log.warn("警告:验证字段为空,无法校验!");
                return;
            }
            formBeanParam = beanClass.newInstance();
            //循环获取需要查重的属性
            for (String fieldName : validateFields) {
                Field field = null;
                try {
                    field = beanClass.getDeclaredField(fieldName);
                } catch (NoSuchFieldException e) {
                    log.warn("警告:formBean验证字段【{}】不存在!", fieldName);
                    throw new IllegalArgumentException("警告:formBean验证字段【" + fieldName + "】不存在!");
                }
                try {
                    dtoClass.getDeclaredField(fieldName);
                } catch (NoSuchFieldException e) {
                    log.warn("警告:dtoBean验证字段【{}】不存在!", fieldName);
                    throw new IllegalArgumentException("警告:dtoBean验证字段【" + fieldName + "】不存在!");
                }
                field.setAccessible(true);
                Object fieldValue = field.get(formBean);
                if (Objects.isNull(fieldValue) || (fieldValue instanceof String && StringUtil.isEmpty((String) fieldValue))) {
                    log.info("提示:formBean验证字段【{}】值为空,无需验证!", field.getName());
                    isNull = true;
                    break;
                }
                field.set(formBeanParam, fieldValue);
            }
            if (!isNull) {
                dtoBean = JSON.parseObject(JSON.toJSONString(formBeanParam), dtoClass);
                num = baseService.selectCount(dtoBean);
                result = duplicateJudgment(num, idFields, ids, dtoBean, baseService);
                if (!result) {
                    resultCode.set(false);
                    repeatMsg = unionRepeat.msg();
                    throw new CdtBissException(repeatMsg);
                }
            }
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值