Java自定义注解
4242 点击·0 回帖
![]() | ![]() | |
![]() | java注解目前广泛被应用。spring中的基于注解的依赖注入、Spring web MVC中的Route、PlayFramework中的基于注解的Validation等。 使用注解,可以在适当地方替代XML的繁琐。 现在来看看,如何自定义注解。 目标:通过注解方式,定义属性的默认值。例如: [java] public class DefaultUse { @Default(value = "Hello Annotation") private String msg; public void say(){ System.out.println(msg); } } public class DefaultUse { @Default(value = "Hello Annotation") private String msg; public void say(){ System.out.println(msg); } } 一、新建Annotation [java] import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Retention 指定注释的生存时期 * CLASS:注释记录在类文件中,但在运行时 VM 不需要保留注释。 * RUNTIME:注释记录在类文件中,在运行时 VM 将保留注释,因此可以使用反射机制读取注释内容。 * SOURCE:编译器要丢弃的注释。 */ @Retention(RetentionPolicy.RUNTIME) /** * @Target * 指示注释类型所适用的程序元素的种类,如果注释类型声明中不存在 Target 元注释, * 则声明的类型可以用在任一程序元素上。 * ElementType.ANNOTATION_TYPE:注释类型声明 * ElementType.CONSTRUCTOR:构造方法声明 * ElementType.FILED:字段声明 * ElementType.LOCAL_VARIABLE:局部变量声明 * ElementType.METHOD:方法声明 * ElementType.PACKAGE:包声明 * ElementType.PARAMETER:参数声明 * ElementType.TYPE:类、借口或枚举声明 */ @Target(ElementType.FIELD) public @interface Default { String value(); //默认值 } import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Retention 指定注释的生存时期 * CLASS:注释记录在类文件中,但在运行时 VM 不需要保留注释。 * RUNTIME:注释记录在类文件中,在运行时 VM 将保留注释,因此可以使用反射机制读取注释内容。 * SOURCE:编译器要丢弃的注释。 */ @Retention(RetentionPolicy.RUNTIME) /** * @Target * 指示注释类型所适用的程序元素的种类,如果注释类型声明中不存在 Target 元注释, * 则声明的类型可以用在任一程序元素上。 * ElementType.ANNOTATION_TYPE:注释类型声明 * ElementType.CONSTRUCTOR:构造方法声明 * ElementType.FILED:字段声明 * ElementType.LOCAL_VARIABLE:局部变量声明 * ElementType.METHOD:方法声明 * ElementType.PACKAGE:包声明 * ElementType.PARAMETER:参数声明 * ElementType.TYPE:类、借口或枚举声明 */ @Target(ElementType.FIELD) public @interface Default { String value(); //默认值 } 二、实际类中使用 [java] public class DefaultUse { @Default(value = "Hello Annotation") private String msg; public void setMsg(String msg) { this.msg = msg; } public void say(){ System.out.println(msg); } } public class DefaultUse { @Default(value = "Hello Annotation") private String msg; public void setMsg(String msg) { this.msg = msg; } public void say(){ System.out.println(msg); } } 三、注解解析过程 [java] import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class DefaultTest { public static void main(String args[]) throws Exception{ DefaultUse use = new DefaultUse(); //Default注解的处理过程 //这里使用反射机制完成默认值的设置 Field[] fileds = use.getClass().getDeclaredFields(); for(Field filed : fileds){ Default annotation = filed.getAnnotation(Default.class); if(annotation != null){ PropertyDescriptor pd = new PropertyDescriptor(filed.getName(), DefaultUse.class); Method setterName = pd.getWriteMethod(); if(setterName!=null){ String value = annotation.value(); filed.setAccessible(true); setterName.invoke(use, value); } } } use.say(); } } import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class DefaultTest { public static void main(String args[]) throws Exception{ DefaultUse use = new DefaultUse(); //Default注解的处理过程 //这里使用反射机制完成默认值的设置 Field[] fileds = use.getClass().getDeclaredFields(); for(Field filed : fileds){ Default annotation = filed.getAnnotation(Default.class); if(annotation != null){ PropertyDescriptor pd = new PropertyDescriptor(filed.getName(), DefaultUse.class); Method setterName = pd.getWriteMethod(); if(setterName!=null){ String value = annotation.value(); filed.setAccessible(true); setterName.invoke(use, value); } } } use.say(); } } | |
![]() | ![]() |