注解(Annotation)源码解析--简单实现(Hibernate,EJB,JPA)

注解提供了一种结构化的,并且具有类型检查能力的新途径,从而使程序员能够为代码加入元数据,而不会导致代码杂乱且难以理解。如:@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 getAnnotation(Class annotationClass) {
        if (annotationClass == null)
            throw new NullPointerException();
        return (T) declaredAnnotations().get(annotationClass);// 调用声明的注解方法,获得指定@Column类型的注解
    }


AnnotationParser.declaredAnnotations(...)方法

private synchronized  Map 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 parseAnnotations(byte[] paramArrayOfByte, ConstantPool paramConstantPool, Class paramClass)
  {
// {code...}
        return parseAnnotations2(paramArrayOfByte, paramConstantPool, paramClass);// 调用parseAnnotations2方法
// {code...}
 }


AnnotationParser.parseAnnotations2(...)方法

private static Map 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 paramMap)
  {
    return (Annotation)Proxy.newProxyInstance(paramClass.getClassLoader(), new Class[] { paramClass }, new AnnotationInvocationHandler(paramClass, paramMap));
// 创建@Column对象
  }


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


其实,在Java中这些个东西好似很难实现(对‘自己’来说),但是你看看源代码,看看他的设计理念,也许也会有自己的一番见解和学习,了解Java的API的实现,这需要有耐心,要耐得住寂寞。

你可能感兴趣的:(Java)