import java.lang.annotation.*;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimeStatistics {
}
class TimeStatisticsAspect {
@Around("@annotation(com.example.TimeStatistics)")
public Object statisticsTime(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
String methodName = method.getName();
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println(methodName + " 方法执行时间为 " + elapsedTime + " ms");
return result;
}
}
上面的代码中,定义了一个名为 TimeStatistics 的注解,它可以用于方法上,并且没有任何属性。在注解的实现类 TimeStatisticsAspect 中,使用了 AspectJ 的切面编程来实现对注解的处理。在 statisticsTime 方法中,获取了被注解的方法的名称、开始执行时间、结束执行时间,通过计算两个时间之间的差值得到了方法的执行时间,最后将结果输出到控制台中。
使用注解时,只需要在需要统计执行时间的方法上添加 @TimeStatistics 注解即可。当方法被调用时,该注解会自动触发 statisticsTime 方法,并将方法的执行时间输出到控制台中。例如:
@TimeStatistics
public void myMethod() {
// method body
}
在 Java 中,可以通过编写自定义注解来实现对代码的扩展和注释。下面是一个简单的自定义注解的示例代码:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String value() default "";
}
上面的代码定义了一个名为 MyAnnotation 的注解,它可以用于类、接口和枚举上,并包含一个名为 value 的属性。可以使用 @Retention 注解来指定注解的生命周期,@Target 注解来指定注解的作用目标。
可以在类或方法上使用 MyAnnotation 注解,例如
@MyAnnotation(value = "example")
public class MyClass {
// class body
}
Java 中的注解可以通过 @Target 注解来限定它们能够应用的目标元素。@Target 是一个元注解,用于注解其他注解,并指定该注解可以应用的目标元素的类型,它的取值包括以下几种:
- ElementType.TYPE:用于类、接口和枚举类型;
- ElementType.FIELD:用于字段(包括枚举常量);
- ElementType.METHOD:用于方法;
- ElementType.PARAMETER:用于方法参数;
- ElementType.CONSTRUCTOR:用于构造函数;
- ElementType.LOCAL_VARIABLE:用于局部变量;
- ElementType.ANNOTATION_TYPE:用于注解类型;
- ElementType.PACKAGE:用于包。
注解可以用于不同的目标元素上,而不同的目标元素有不同的作用,因此在定义注解时需要指定它所能够应用的目标元素类型。例如,一个注解可能只用于方法上,而不能应用于其他元素上。
使用 @Target 注解时,需要将其放置在注解定义的前面,并传入一个 ElementType 枚举类型的数组,指定该注解可以应用的目标元素类型。
@Retention
注解用来指定注解的生命周期,即注解在什么级别保存,在什么时候丢弃。在 Java 中,共有三个级别:
RetentionPolicy.SOURCE
: 在源文件中有效,编译器直接丢弃这种注解。RetentionPolicy.CLASS
: 在类文件中有效,但是运行时无法获得,这是默认的保留策略。RetentionPolicy.RUNTIME
: 在运行时有效,可以通过反射机制读取。
通常来说,我们需要在运行时读取注解信息,所以需要使用 @Retention(RetentionPolicy.RUNTIME)
进行注解声明。