使用Annotation的示例
自定义注解是,通常都会使用反射。
Example:
定义一个标识接口,运行时期 RUNTIME
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Testable {
}
public class MyTest {
@Testable
public static void m1() {
}
@Testable
public static void m2() {
}
@Testable
public static void m3() {
}
@Testable
public static void m4() {
}
@Testable
public static void m5() {
}
@Testable
public static void m6() {
throw new RuntimeException("Boom");
}
@Testable
public static void m7() {
throw new RuntimeException("Crash");
}
}
使用反射来运行:
public class ProcessTest {
public static void process(String clazz) throws ClassNotFoundException {
int passed = 0;
int failed = 0;
for (Method m : Class.forName(clazz).getMethods()) {
if (m.isAnnotationPresent(Testable.class)) {
try {
m.invoke(null);
passed++;
} catch (Exception e) {
e.getStackTrace();
failed++;
}
}
}
System.out.println("共运行了: " + (passed + failed) + " 个方法,其中失败了: " + failed + "个,成功了: " + passed + "个。");
}
public static void main(String[] args) throws Exception {
process("com.beng.annotation.MyTest");
}
}
注解的原理,基本都是这样。
例如 hibernate 利用工具反射出 xml 文件,就是利用 APT 工具。
APT(Annotation Processing Tool)是一种处理注释的工具,可以对源代码文件进行检测找出其中的Annotation,并对其进行处理。
例如 morphia 中的 @Entity 注解
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface Entity {
...
}
我在实际的项目中也有使用 hibernate-validator 的注解实现字段校验。
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.2.Final</version>
</dependency>
通过注解 @Constraint 实现自定义的注解。