Java自定义注解

1. 自定义注解

通过上篇文章中对注解基础知识的说明,自定义注解其实就是用Java提供的元注解声明的一种注解类型。

下面以一个定时任务注解的例子说明自定义注解的声明、使用以及处理

1.1 自定义注解的声明

下面定义了一个定时任务的自定义注解@Schedule,包含三个元素scheduleName cron desc

自定义注解时候,若给元素设置有默认值,则使用时候可不指定其值(如下例中的desc元素)。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Schedule {
    /**
     * Schedule名称
     */
    String scheduleName();

    /**
     * Schedule执行表达式
     */
    String cron();

    /**
     * Schedule描述
     */
    String desc() default "";
}

1.2 自定义注解的使用

下面定义了一个业务处理类CustAnnotationsService,包含一个handler方法,该方法需要被定时触发执行,使用上面自定义的注解@Schedule

public class CustAnnotationsService {

    @Schedule(scheduleName = "sc1", cron = "0 0/30 * * * ?")
    public void handler(){
        System.out.println("do something ...");
    }
}

1.3 自定义注解的处理

在上篇文章中提到过,自定义注解对代码的本身的执行没有什么影响,那么要想通过注解实现特定逻辑,就需要对自定义注解进行处理。自定义注解的处理,主要是通过反射 API实现的。

注解处理的反射API详见下篇

以下是读取注解的处理类示例(根据@Schedule自定义注解生成Quartz定时任务,下面不做扩展)

public class TestHandlerAnnotations {
    public static void main(String[] args) {
        Method[] methods = CustAnnotationsService.class.getDeclaredMethods();
        for (Method m : methods){
            Schedule[] scheduleArr = m.getAnnotationsByType(Schedule.class); //兼容注解和重复注解容器的获取
            for (Schedule schedule : scheduleArr){
                System.out.println(String.format("method name = %s; schedule : scheduleName = %s, cron = %s, desc = %s",
                        m.getName(), schedule.scheduleName(), schedule.cron(), schedule.desc()));
            }
        }
    }
}

输出结果如下:

method name = handler; schedule : scheduleName = sc1, cron = 0 0/30 * * * ?, desc = 

2. 重复注解

2.1 何为重复注解

在某些场景下,需要在同一个程序元素上声明多个注解,对于一个注解声明多次,即是重复注解重复注解在Java SE 8才被引入。

2.2 重复注解容器

重复注解容器是一个特殊的自定义注解,重复使用的自定义注解被存储在重复注解容器中,这个动作由编译器自动完成。重复注解容器声明的元注解使用与普通自定义注解一致,其包含一个value元素,value元素的类型为自定义注解数组

还是以上面的定时任务注解为例,若我们需要为定时执行的方法定义两种不同维度的执行触发条件,则可以在方法上声明多个自定义注解。这种情况下我们为自定义注解@Schedule声明一个重复注解容器为@Schedules,如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Schedules {
    Schedule[] value();
}

2.3 自定义注解声明可重复

自定义的注解声明可重复是通过在自定义注解的声明上添加@Repeatable元注解(Java SE 8被引入),且值为重复注解容器类型

下面我们对例子中的自定义注解@Schedule进行改造,使其变为可重复注解。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Repeatable(Schedules.class)
public @interface Schedule {
    /**
     * Schedule名称
     */
    String scheduleName();

    /**
     * Schedule执行表达式
     */
    String cron();

    /**
     * Schedule描述
     */
    String desc() default "";
}

2.4 重复注解的使用

在业务处理类CustAnnotationsService中,新增一个handler2方法,该方法上使用了两个自定义的注解@Schedule

public class CustAnnotationsService {

    @Schedule(scheduleName = "sc1", cron = "0 0/30 * * * ?")
    public void handler(){
        System.out.println("do something ...");
    }

    @Schedule(scheduleName = "sc21", cron = "0 0 23 * * ?", desc = "每天23点执行一次")
    @Schedule(scheduleName = "sc22", cron = "0 0 1 * * ?", desc = "每天凌晨1点执行一次")
    public void handler2(){
        System.out.println("do something ...");
    }
}

2.5 重复注解处理

上面例子中自定义注解处理类TestHandlerAnnotations在使用反射API处理自定义注解时候,使用的是兼容获取重复注解容器的API方法getAnnotationsByType。因此无需修改注解处理类TestHandlerAnnotations,再次执行,输出结果如下:

method name = handler; schedule : scheduleName = sc1, cron = 0 0/30 * * * ?, desc = 
method name = handler2; schedule : scheduleName = sc21, cron = 0 0 23 * * ?, desc = 每天23点执行一次
method name = handler2; schedule : scheduleName = sc22, cron = 0 0 1 * * ?, desc = 每天凌晨1点执行一次

本文翻译整理自java官网:
Declaring an Annotation Type
Repeating Annotations

传送门======>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值