美文网首页
java注解

java注解

作者: 虫二无边 | 来源:发表于2016-06-12 17:39 被阅读70次

    什么是注解?

    注解就是代码的元数据,他们包含了代码自身的信息。那么什么又是元数据?元数据是指描述数据的数据,描述数据属性的信息。

    注解可以被用在包,类,方法,变量,参数上。自Java8起,有一种注解几乎可以被放在代码的任何位置,叫做类型注解。

    注解的使用场景

    • 编译检查
    • 文档
    • 代码生成 根据注解生成代码或者xml。 如JAXB
    • 运行时处理 如junit, orm,spring等

    自定义注解

    @Target
    用于描述注解的使用范围

    1. CONSTRUCTOR:用于描述构造器
    2. FIELD:用于描述域
    3. LOCAL_VARIABLE:用于描述局部变量
    4. METHOD:用于描述方法
    5. PACKAGE:用于描述包
    6. PARAMETER:用于描述参数
    7. TYPE:用于描述类、接口(包括注解类型) 或enum声明

    @Retention
    用于描述注解的生命周期

    1. SOURCE:在源文件中有效(即源文件保留)
    2. CLASS:在class文件中有效(即class保留)
    3. RUNTIME:在运行时有效(即运行时保留)

    @Documented
    Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API

    @Inherited
    @Inherited表示是可以被继承的, 如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类

    示例:

    target class:

    @Target( ElementType.TYPE )
    @Retention( RetentionPolicy.RUNTIME )
    @Documented
    @Inherited
    public @interface CustomAnnotationClass implements CustomAnnotationMethod {
         public String author() default "danibuiza";
         public String date();
    }
    

    使用:

    @CustomAnnotationClass( date = "2014-05-05" )
    public class AnnotatedClass
    {
    }
    

    target method:

    @Retention( RetentionPolicy.RUNTIME )
    @Target( ElementType.METHOD )
    public @interface CustomAnnotationMethod
    {
     
     public String author() default "danibuiza";
     
     public String date();
     
     public String description();
     
    }
    

    使用:

    @CustomAnnotationMethod( author = "friend of mine", date = "2014-06-05", description = "annotated method" )
    public String annotatedMethodFromAFriend()
    {
       return "nothing niente";
    }
    

    target 属性:

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CustomAnnotationField{
    
        public enum Color{ BULE,RED,GREEN};
        
        Color color() default Color.GREEN;
    
    }
    

    使用:

        @CustomAnnotationField(color=Color.RED)
        private String appleColor;
    

    注解的处理
    java api中提供了通过反射来获取注解.

    • getAnnotations(): 返回该元素的所有注解,包括没有显式定义该元素上的注解。
    • isAnnotationPresent(annotation): 检查传入的注解是否存在于当前元素。
    • getAnnotation(class): 按照传入的参数获取指定类型的注解。返回null说明当前元素不带有此注解。

    示例:

    Class<AnnotatedClass> clazz= AnnotatedClass.class;
    
    // 判断 该类 是否存在注解
     if( clazz.isAnnotationPresent( CustomAnnotationClass.class ) )
     {
     
         // 获取类注解
         Annotation annotation = clazz.getAnnotation( CustomAnnotationClass.class );
         System.out.println( annotation );
     
     }
     // 获取method 注解
     for( Method method : clazz.getDeclaredMethods() )
     {
     
        //判断方法是否存在注解
       if( method.isAnnotationPresent( CustomAnnotationMethod.class ) )
       {
           Annotation annotation = method.getAnnotation( CustomAnnotationMethod.class );
           System.out.println( annotation );
       }
    }
    
     Field[] fields = clazz.getDeclaredFields();
            
     for(Field field :fields ){
           if(field.isAnnotationPresent(CustomAnnotationField.class)){
                CustomAnnotationField field = (FruitName) field.getAnnotation(CustomAnnotationField.class);
                System.out.println(field );
           }
     }
    

    另外一个实例, 结合动态代理进行权限控制:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface RequiredRoles {
        String[] value();
    }
    
    public class AccessInvocationHandler<T> implements InvocationHandler {
        final T accessObj;
        public AccessInvocationHandler(T accessObj) {
            this.accessObj = accessObj;
        }
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            RequiredRoles annotation = method.getAnnotation(RequiredRoles.class); //通过反射API获取注解
            if (annotation != null) {
                String[] roles = annotation.value();
                String role = AccessControl.getCurrentRole();
                if (!Arrays.asList(roles).contains(role)) {
                    throw new AccessControlException("The user is not allowed to invoke this method.");
                }
            }
            return method.invoke(accessObj, args);
        } 
    } 
    

    参考:
    http://www.importnew.com/14227.html
    http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
    http://www.infoq.com/cn/articles/cf-java-annotation
    扩展: 主要是AbstractProcessor 的使用技巧
    http://blog.csdn.net/lmj623565791/article/details/43452969
    http://blog.csdn.net/lmj623565791/article/details/39275847
    http://www.cnblogs.com/avenwu/p/4173899.html

    相关文章

      网友评论

          本文标题:java注解

          本文链接:https://www.haomeiwen.com/subject/lkuedttx.html