Java 自定义注解_java自定义注解声明关键字-程序员宅基地

技术标签: spring boot  java  Spring Boot  

像平时用到的 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);
                }
            }
        }

    }
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Amme12123/article/details/130536041

智能推荐

python多进程 保活_转: android app进程保活的文章列表-程序员宅基地

文章浏览阅读44次。从CIO、CEO、CFO、COO&period;&period;&period;到CVO 这22个你了解几个&quest; &lpar;史上最完整版&rpar;1.CEO:是Chief Executive Officer的缩写,即首席执行官. 由于市场风云变幻,决策的速度和执行的力度比以往任何时候都更加重要.传统的“董事会决策.经理层执行”的公司体制..._安卓进程保活

如何高效优雅的完成一次机器学习服务部署?一文详解部署难点以及实战案例_机器学习模型的云端服务器部署-程序员宅基地

文章浏览阅读2.2w次,点赞582次,收藏582次。数据准备:从公共数据集中获取数据,并进行数据清洗和特征工程处理,将数据转化为适合机器学习算法处理的格式。创建SageMaker Notebook实例:通过AWS Management Console或AWS SDK创建SageMaker Notebook实例,并连接到实例。编写代码:在Notebook中编写代码,使用Amazon SageMaker提供的XGBoost算法和数据输入通道,加载并处理数据,训练并评估模型。模型调优:通过调整模型的参数和超参数,优化模型性能。_机器学习模型的云端服务器部署

Sublime text 3搭建Python开发环境及常用插件安装_sublime python 环境搭建-程序员宅基地

文章浏览阅读4.9k次。Sublime text 3搭建Python开发环境及常用插件安装_sublime python 环境搭建

在CentOS 7上安装MySQL 8.0_centos7安装mysql8.0gpg密钥-程序员宅基地

文章浏览阅读643次。MySQL在首次安装后会执行一个安全脚本,用于设置root用户的密码以及其他安全选项。_centos7安装mysql8.0gpg密钥

echarts绘制圆角方形进度图_echarts symbolboundingdata-程序员宅基地

文章浏览阅读864次。这种场景下,可以使用两个系列,一个系列是完整的图形,当做『背景』来表达总数值,另一个系列是使用 `symbolClip` 进行剪裁过的图形,表达当前数值。_echarts symbolboundingdata

学python需要什么样的电脑,python需要什么样的电脑_python机器学习需要怎样配置的电脑-程序员宅基地

文章浏览阅读1k次,点赞18次,收藏16次。这篇文章主要介绍了学python对电脑配置要求高吗,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。_python机器学习需要怎样配置的电脑

随便推点

模型部署——RKNN模型量化精度分析及混合量化提高精度_if set do_quantization = true-程序员宅基地

文章浏览阅读508次,点赞4次,收藏8次。3.1 量化精度分析流程计算不同情况下,同一层网络输入值的余弦距离,来近似的查看每一层精度损失的情况。具体量化精度分析的流程如下:3.2 量化精度分析accuracy_analysis接口量化精度分析调用accuracy_analysis接口,推理并产生快照,也就是dump出每一层的tensor数据。会dump出包括fp32和quant两种数据类型的快照,用于计算量化误差。该接口使用的量化方式与config_中指定的一致。_if set do_quantization = true

汽车整车EMC检测-程序员宅基地

文章浏览阅读512次,点赞15次,收藏6次。摘要:RE辐射、CE传导、BCI大电流注入,ESD静电、ISO7637瞬态脉冲干扰等EMC测试、EMC整改,一站式服务,双C报告

docker安装PHP5.6 提示 does not have a Release file_docker php5.6-程序员宅基地

文章浏览阅读276次。docker安装PHP5.6_docker php5.6

TPC-B测试:Greenplum 6版本比5版本到底好了多少?_tpcb测试-程序员宅基地

文章浏览阅读1.3k次。pgbench 简介:pgbench是一种在PostgreSQL上运行基准测试的简单程序。它可能在并发的数据库会话中一遍一遍地运行相同序列的 SQL 命令,并且计算平均事务率(每秒的事务数)。默认情况下,pgbench会测试一种基于 TPC-B 但是要更宽松的场景,其中在每个事务中涉及五个SELECT、UPDATE以及INSERT命令。但是,通过编写自己的事务脚本文件很容易用来测试其他情况..._tpcb测试

[ATF]-TEE/REE系统切换时ATF的寄存器的保存和恢复_atf-tee-程序员宅基地

文章浏览阅读1k次。ATF点滴1、设置运行时栈SP2、寄存器的保存和恢复的实现3、寄存器的保存和恢复的使用场景1、设置运行时栈SPbl31_entrypoint—>el3_entrypoint_common---->plat_set_my_stack—>platform_set_stack—>platform_get_stack动态找到该cpufunc platform_set_stackmov x9, x30 // lrbl platform_get_stackmov sp, x0r_atf-tee

PPT模板下载-程序员宅基地

文章浏览阅读134次。300多个各种类型的PPT模板下载,为您提供各种类型PPT模板、PPT图片、PPT素材、海报模板、新媒体配图等内容下载。