灯火互联
管理员
管理员
  • 注册日期2011-07-27
  • 发帖数41778
  • QQ
  • 火币41290枚
  • 粉丝1086
  • 关注100
  • 终身成就奖
  • 最爱沙发
  • 忠实会员
  • 灌水天才奖
  • 贴图大师奖
  • 原创先锋奖
  • 特殊贡献奖
  • 宣传大使奖
  • 优秀斑竹奖
  • 社区明星
阅读:3648回复:0

Java自定义注解

楼主#
更多 发布于:2012-09-08 09:39


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();
}
}


喜欢0 评分0
游客

返回顶部