注解字面意思好像是 注释,提示和说明的做用,可是这样对于刚接触这个概念的人,很难理解究竟注解是用来干吗的. 好比 Spring MVC中的@Controller, Mybatis中的 @Column. 其实用大白话来讲: 注解最大的做用就是替代设计框架的不少的xml文件,使用JAVA的反射机制来读取注解上的内容,方便框架的使用者. 下面咱们就来一步一步的使用注解来自定义本身的Mybatis框架.java
首先 注解有几个重要的元注解,也就是在使用JDK自带的元注解的基础上才能自定义本身的注解框架
1.一、@Retention: 定义注解的策略,大白话就是定义注解的范围函数
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含 @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但 运行时没法得到, @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时能够经过反射 获取到
1.2 @Target:定义注解的目标,大白话就是注解是 类,接口仍是方法或者参数this
@Target(ElementType.TYPE) //接口、类、枚举、注解 @Target(ElementType.FIELD) //字段、枚举的常量 @Target(ElementType.METHOD) //方法 @Target(ElementType.PARAMETER) //方法参数 @Target(ElementType.CONSTRUCTOR) //构造函数 @Target(ElementType.LOCAL_VARIABLE)//局部变量 @Target(ElementType.ANNOTATION_TYPE)//注解 @Target(ElementType.PACKAGE) ///包
2.1. Table的定义设计
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE }) public @interface Table { String name() default ""; }
2.2. Column的定义code
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { boolean isKey() default false; String value() default ""; }
2.3. 框架使用者定义的User列表xml
@Table(name = "User") public class User { @Column(value = "id", isKey = true) private int id; @Column(value = "name") private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Annotation { private static void parseAnnotation(Class clazz) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, SecurityException, InvocationTargetException { Table table = (Table) clazz.getAnnotation(Table.class); System.out.println("table name: " + table.name()); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { Column column = (Column) field.getAnnotation(Column.class); System.out.println("column name: " + column.value() + " isKey: " + column.isKey()); String fieldName = field.getName(); Class<?> type = field.getType(); System.out.println("field name: " + fieldName + " type: " + type); } } public static void main(String args[]) throws IllegalArgumentException, IllegalAccessException, NoSuchMethodException, SecurityException, InvocationTargetException { User user = new User(); user.setId(1112111); user.setName("test"); parseAnnotation(user.getClass()); } }