注解字面意思好像是 注释,提示和说明的作用,但是这样对于刚接触这个概念的人,很难理解究竟注解是用来干嘛的. 比如 Spring MVC中的@Controller, Mybatis中的 @Column. 其实用大白话来说: 注解最大的作用就是替代设计框架的很多的xml文件,使用JAVA的反射机制来读取注解上的内容,方便框架的使用者. 下面我们就来一步一步的使用注解来自定义自己的Mybatis框架.
-
首先 注解有几个重要的元注解,也就是在使用JDK自带的元注解的基础上才能自定义自己的注解
1.1、@Retention: 定义注解的策略,大白话就是定义注解的范围
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但 运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射 获取到
1.2 @Target:定义注解的目标,大白话就是注解是 类,接口还是方法或者参数
@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) ///包
- 说了理论的知识,我们自己手动来写一个Mybatis的框架注解
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的定义
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
boolean isKey() default false;
String value() default "";
}
2.3. 框架使用者定义的User列表
@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());
}
}