`
taogebx
  • 浏览: 33559 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[转载]Java注解--源码解析

阅读更多

注解提供了一种结构化的,并且具有类型检查能力的新途径,从而使程序员能够为代码加入元数据,而不会导致代码杂乱且难以理解。如:@Override 说明继承类或实现接口方法重载。

 

注解是在实际的源代码级别保存所有的信息,而不是某种注释性的文字。

 

在Hibernate,EJB,JPA中Column实现和应用程序案例:

 

Column.java

    import java.lang.annotation.ElementType;  
    import java.lang.annotation.Retention;  
    import java.lang.annotation.RetentionPolicy;  
    import java.lang.annotation.Target;  
    @Target({ElementType.METHOD,ElementType.FIELD})  
    // 目标可以指定的元素类型方法级别和域(属性)级别  
    @Retention(RetentionPolicy.RUNTIME)  
    // 保留方针为运行时级别,注解可以在运行时通过反射获得  
    public @interface Column {  
     String name() default "";  
     // default 关键字可以为name方法设置默认值  
     boolean unique() default false;  
     boolean nullable() default true;  
     boolean insertable() default true;  
     boolean updateable() default true;  
     String columnDefinition() default "";  
     String secondaryTable() default "";  
     int length() default 255;  
     int precision() default 0;  
     int scale() default 0;  
    }  
 

UseCase.java

    import java.lang.reflect.Field;  
    public class UseCase {  
     @Column(name = "name", length = 20, unique = true)  
     private String name;  
     @Column(name = "description", length = 100)  
     private String description;  
     public String getName() {  
      return name;  
     }  
     public void setName(String name) {  
      this.name = name;  
     }  
     public String getDescription() {  
      return description;  
     }  
     public void setDescription(String description) {  
      this.description = description;  
     }  
     public static void main(String[] args) {  
      Field[] fields = UseCase.class.getDeclaredFields();  
      for (Field field : fields) {  
       Column column = field.getAnnotation(Column.class);  
       System.out.println(column.name() + " " + column.length() + " " + column.unique());  
      }  
     }  
    }  
 

 

控制台显示的结果为:

name 20 true
description 100 false

 

应用程序简单应用源码解析:

1. Field[] fields = UseCase.class.getDeclaredFields();

通过反射,UseCase.class.getDeclaredFields()获得UseCase类的class对象的声明的域。

AnnotationParser.getDeclaredFields(...)方法

 

public Field[] getDeclaredFields() throws SecurityException {  
        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());  
        // 检查类成员访问  
        return copyFields(privateGetDeclaredFields(false));  
        // 返回一份私有获得声明域的拷贝  
    } 

2. for (Field field : fields) {...} // 遍历fields数组

3. Column column = field.getAnnotation(Column.class); // 获得域级别的注解Annotation @Column

 

AnnotationParser.getAnnotation(...)方法

 

    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {  
            if (annotationClass == null)  
                throw new NullPointerException();  
            return (T) declaredAnnotations().get(annotationClass);// 调用声明的注解方法,获得指定@Column类型的注解  
        }  

 

AnnotationParser.declaredAnnotations(...)方法


    private synchronized  Map<Class, Annotation> declaredAnnotations() {  
            if (declaredAnnotations == null) {  
                declaredAnnotations = AnnotationParser.parseAnnotations(  
                    annotations, sun.misc.SharedSecrets.getJavaLangAccess().  
                    getConstantPool(getDeclaringClass()),  
                    getDeclaringClass());  
    // 注解解析,annotations为byte[],sun.misc.SharedSecrets.getJavaLangAccess().  
    // getConstantPool(getDeclaringClass()) 注入getDeclaringClass())即UseCase.class对象,获得Java语言访问的常量池  
            }  
            return declaredAnnotations;  
        }  
 

 

AnnotationParser.parseAnnotations(...)方法

 

public static Map<Class, Annotation> parseAnnotations(byte[] paramArrayOfByte, ConstantPool paramConstantPool, Class paramClass)  
  {  
// {code...}  
        return parseAnnotations2(paramArrayOfByte, paramConstantPool, paramClass);// 调用parseAnnotations2方法  
// {code...}  
 }  

 

AnnotationParser.parseAnnotations2(...)方法


    private static Map<Class, Annotation> parseAnnotations2(byte[] paramArrayOfByte, ConstantPool paramConstantPool, Class paramClass)  
      {  
        LinkedHashMap localLinkedHashMap = new LinkedHashMap();// 声明一个链表的HashMap  
        ByteBuffer localByteBuffer = ByteBuffer.wrap(paramArrayOfByte);// 将字节数组装入ByteBuffer中  
        int i = localByteBuffer.getShort() & 0xFFFF;// 获得localByteBuffer的大小  
        for (int j = 0; j < i; ++j) {  
          Annotation localAnnotation = parseAnnotation(localByteBuffer, paramConstantPool, paramClass, false);  
    //解析Annotation  
          if (localAnnotation != null) {  
            Class localClass = localAnnotation.annotationType();  
            AnnotationType localAnnotationType = AnnotationType.getInstance(localClass);  
    //  AnnotationType获得注解类型  
            if ((localAnnotationType.retention() != RetentionPolicy.RUNTIME) ||   
              (localLinkedHashMap.put(localClass, localAnnotation) == null)) continue;  
    // 说明注解@Column的保留方针必须为RUNTIME级别,并将注解类型和注解对象放入localLinkedHashMap中  
            throw new AnnotationFormatError("Duplicate annotation for class: " + localClass + ": " + localAnnotation);  
          }  
        }  
        return localLinkedHashMap;  
      }

 

AnnotationParser.parseAnnotation(...)方法

 

    private static Annotation parseAnnotation(ByteBuffer paramByteBuffer, ConstantPool paramConstantPool, Class paramClass, boolean paramBoolean)  
      {  
        int i = paramByteBuffer.getShort() & 0xFFFF;  
        Class localClass1 = null;  
        String str1 = paramConstantPool.getUTF8At(i);//获得Column  
        localClass1 = parseSig(str1, paramClass);// 通过UseCase和Column解析得到@Column接口class对象  
        //{code...}  
        AnnotationType localAnnotationType = AnnotationType.getInstance(localClass1);//获得注解类型@Column  
            Map localMap = localAnnotationType.memberTypes();// 获得注解@Column的成员类型  
        LinkedHashMap localLinkedHashMap = new LinkedHashMap(localAnnotationType.memberDefaults());  
    //@Column的成员类型的默认值放入localLinkedHashMap  
        int j = paramByteBuffer.getShort() & 0xFFFF;  
        for (int k = 0; k < j; ++k) {  
          int l = paramByteBuffer.getShort() & 0xFFFF;  
          String str2 = paramConstantPool.getUTF8At(l);// 获得成员类型的名称如name  
          Class localClass2 = (Class)localMap.get(str2);  
                  Object localObject = parseMemberValue(localClass2, paramByteBuffer, paramConstantPool, paramClass);  
    //获得成员的值如name的值为"name"  
                   localLinkedHashMap.put(str2, localObject);  
    //{code...}  
    }  
        return annotationForMap(localClass1, localLinkedHashMap);  
    // 通过@Column.class对象和localLinkedHashMap创建@Column对象  
    }  

 

 AnnotationParser.annotationForMap(...)方法

 

    public static Annotation annotationForMap(Class paramClass, Map<String, Object> paramMap)  
      {  
        return (Annotation)Proxy.newProxyInstance(paramClass.getClassLoader(), new Class[] { paramClass }, new AnnotationInvocationHandler(paramClass, paramMap));  
    // 创建@Column对象  
      }  
 

 

看过源码实现之后,其实就是通过Java的反射机制和代理类来创建指定域(方法或者类)的注解接口对象以及他的属性。

 

分享到:
评论

相关推荐

    JAVA 注解---积累

    在Java编程语言中,注解(Annotation)是一种元数据,它提供了一种安全的方法来将信息附加到代码中,而不改变代码的行为。注解在Java中扮演着重要的角色,主要用于编译时检查、运行时处理、文档生成以及框架的自动...

    基于java的-109-java学习平台--LW-源码.zip

    《基于Java的109号Java学习平台-LW源码解析》 在计算机科学领域,尤其是软件开发中,源码是程序设计的基础,它揭示了软件的内部运作机制。本资料包“基于java的-109-java学习平台--LW-源码.zip”提供了一个完整的...

    基于java的-129-jspm影院管理系统--LW-源码.zip

    《基于Java的JSPM影院管理系统源码解析》 该压缩包文件名为“基于java的-129-jspm影院管理系统--LW-源码.zip”,显然,它包含了一个使用Java语言开发的JSPM(可能代表Java Simple Project Management)影院管理系统...

    Java 第二阶段建立编程思想 【枚举和注解】---- 代码

    Java 第二阶段建立编程思想 【枚举和注解】---- 代码 Java 第二阶段建立编程思想 【枚举和注解】---- 代码 Java 第二阶段建立编程思想 【枚举和注解】---- 代码 Java 第二阶段建立编程思想 【枚举和注解】---- 代码 ...

    javaBook-src-源码.rar

    【标题】"javaBook-src-源码.rar" 提供的是一份关于 Java 语言的源码集合,很可能是某个Java编程书籍的配套源代码。这个压缩包可能包含了多个示例程序、练习项目或者完整的应用程序,旨在帮助学习者深入理解Java编程...

    JAVA设计模式--程序设计--反射--注解--泛型

    Java设计模式、程序设计、反射、注解和泛型是Java开发中的核心概念,它们各自在不同的场景下发挥着重要作用,构建出高效、可维护的软件系统。 首先,Java设计模式是面向对象编程中的一种最佳实践,是解决常见问题的...

    ---注解---.xmind

    ---注解---.xmind Java常用各种注解

    java-basics-源码.rar

    Java基础源码解析 在Java编程领域,理解基础至关重要,因为它是进阶学习和实际开发的基石。"java-basics-源码.rar"文件显然包含了关于Java基础知识的源代码示例,这为我们提供了深入理解语言机制的机会。让我们逐一...

    java-katas-源码.rar

    《Java Katas源码解析》 Java Katas是一种编程练习,旨在提升开发者在Java语言中的技能和熟练度。这些练习通常包含一系列小任务,每个任务都聚焦于特定的编程概念或技术,帮助开发者通过实践来巩固和加深理解。在...

    基于java的-183-ssm基于SSM的个性化商铺系统--LW-源码.zip

    该压缩包文件“基于java的-183-ssm基于SSM的个性化商铺系统--LW-源码.zip”包含了一个使用Java编程语言开发的SSM(Spring、SpringMVC、MyBatis)框架的个性化商铺系统。SSM是Java Web开发中常见的三层架构模式,它将...

    java-1.8.0-openjdk.linux.x86_64

    其中,JVM是Java的核心,它负责解析和执行字节码,使得Java程序可以在任何支持Java的平台上运行,实现了“一次编写,到处运行”的理念。 OpenJDK 1.8.0 版本包含了Java语言的关键特性,如泛型、枚举、匿名内部类、...

    Java基础语法测试-基础数据类型-注解-数组-inet-反射-oop-Java代码实现

    内容概要:通过带着读者编写Java基础语法测试代码,理解基础数据类型-注解-数组-inet-反射-oop-Java代码实现过程和测试代码 适合人群:初学java语法入门测试代码 能学到什么:①注解、数组、数据类型、inet、method...

    Java-EE-8-Design-Patterns-and-Best-Practices-源码.rar

    《Java EE 8 设计模式与最佳实践》源码分析 在Java开发领域,Java EE(Enterprise Edition)作为企业级应用开发的标准平台,为开发者提供了丰富的功能和组件。设计模式和最佳实践是Java EE开发中不可或缺的部分,...

    基于java的-77-269家庭食谱管理系统-LW-源码.zip

    综上所述,"基于Java的-77-269家庭食谱管理系统"是一个采用Java编程语言,结合数据库技术,遵循MVC架构,利用注解优化编码,通过模块化设计实现功能分离的软件系统。用户可以借助这个系统,轻松记录、搜索和分享家庭...

    java-经典webservice源码实例

    Java WebService 源码实例详解 WebServices 是一种基于开放标准的,可以在不同操作系统、编程语言和网络之间交换信息的技术。在Java中,我们通常使用JAX-WS(Java API for XML Web Services)框架来创建和消费Web...

    基于java的-133-jspSSM368的药品销售配送网站系统-LW-源码.zip

    这是一个基于Java技术栈的药品销售配送网站系统的源码包,主要使用了JSP、Spring、SpringMVC(SSM)框架。源码的结构清晰,包含多个子目录,用于组织不同的功能模块。以下是对该系统及其相关技术的详细解释: 1. **...

    Java-JDBC【源码】实现ORM,结果集映射实体类(ResultSet、注解、反射)

    Java-JDBC【之】实现ORM,结果集映射实体类(ResultSet、注解、反射) 1.ORM实现思路 2.@Table、@Column、标识实体类 2.1.创建注解 @Table、@Column 2.2.标识实体类 2.3.数据库表 3.结果集解析,注解加反射填充实体...

    java注解解析知识要点

    Java 注解,也称为 Annotation,是自 Java 5 引入的一种元数据,它为代码提供了额外的信息,这些信息可以用于生成文档、分析代码、执行编译时检查以及在运行时处理代码。注释不会直接影响代码的执行逻辑,但可以通过...

    基于Java注解自动化脱敏的secure-ext-spring-boot-starter设计源码

    该项目为基于Java注解的自动化脱敏解决方案,名为secure-ext-spring-boot-starter,共包含40个文件,涵盖27个Java源文件、4个XML配置文件、3个JPG图片文件、2个YAML配置文件、1个Git忽略文件和1个LICENSE文件。...

Global site tag (gtag.js) - Google Analytics