且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java 8 可重复的自定义注解

更新时间:2023-11-26 16:54:10

在 Java 8 之前,给定的注解只能在方法(或类、字段等)上设置一次.因此,如果您希望能够在单个方法上设置两个不同的时间表,则必须定义一个包装"注释,例如 Schedules,其中包含一个 Schedule 数组注释.

因此,开发人员必须执行以下操作:

@Schedules(value = {@Schedule(dayOfMonth="last"),@Schedule(dayOfWeek="Fri", hour="23")})

这不是很容易阅读,并且 Schedules 注释除了包含多个 Schedule 注释之外没有任何其他用途.

为了减少样板,但保持注释 API 相同,现在允许简单地使用

注释方法
@Schedule(dayOfMonth="last"),@Schedule(dayOfWeek="Fri", hour="23")

通过将 Schedule 声明为可重复并指定其包装"注释.但这只是语法糖,结果与前面的代码相同:该方法在运行时被视为使用包含两个 Schedules 的单个 Schedules 注释进行注释.编译器将第二段代码转换为第一段代码.

I know about basic annotations in Java like @Override etc.

Annotations are only metadata and they do not contain any business logic.

I am going through repeating annotations from Oracle documentation page to understand Java 8 new feature.

For example, you are writing code to use a "timer service that enables you to run a method at a given time or on a certain schedule, similar to the UNIX cron service". Now you want to set a timer to run a method, doPeriodicCleanup, on the last day of the month and on every Friday at 11:00 p.m. To set the timer to run, create an @Schedule annotation and apply it twice to the doPeriodicCleanup method.

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

Declare a Repeatable Annotation Type

The annotation type must be marked with the @Repeatable meta-annotation. The following example defines a custom @Schedule repeatable annotation type:

import java.lang.annotation.Repeatable;

@Repeatable(Schedules.class)
public @interface Schedule {
    String dayOfMonth() default "first";
    String dayOfWeek() default "Mon";
    int hour() default 12;
}

Declare the Containing Annotation Type

The containing annotation type must have a value element with an array type. The component type of the array type must be the repeatable annotation type. The declaration for the Schedules containing annotation type is the following:

public @interface Schedules {
    Schedule[] value();
}

I did not understand use and usage of @Schedules annotation. How does it work for below method now? .

public void doPeriodicCleanup() { ... }

Thanks in advance.

Before Java 8, a given annotation could only be set once on a method (or class, or field, etc.). So, if you wanted to be able to set two different schedules on a single method, you had to define a "wrapping" annotation such as Schedules, containing an array of Schedule annotions.

The developer thus had to do something like this:

@Schedules(value = {
    @Schedule(dayOfMonth="last"),
    @Schedule(dayOfWeek="Fri", hour="23")
})

This is not very readable, and the Schedules annotation doesn't have any purpose other than containing several Schedule annotations.

To reduce the boilerplate, but keep the annotations API identical, it's now allowed to simply annotate the method with

@Schedule(dayOfMonth="last"),
@Schedule(dayOfWeek="Fri", hour="23")

by declaring Schedule as repeatable and specifying its "wrapping" annotation. But it's just syntax sugar, that results in the same thing as the previous code: the method, at runtime, is seen as being annotated with a single Schedules annotation containing two Schedule. The compiler transforms the second piece of code into the first one.