什么是注解?
Jdk1.5新增新技术,注解。很多框架为了简化代码,都会提供有些注解。可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
注解分类:内置注解(也称为元注解 jdk 自带注解)、自定义注解(Spring框架)
什么是内置注解
比如
(1) @SuppressWarnings 再程序前面加上可以在javac编译中去除警告
(2) @Deprecated 带有标记的包,方法,字段说明其过时
(3)@Overricle 打上这个标记验证该方法是将父类的方法重写
那么如何自定义注解呢?
要想自定义注解,先看看jdk内置的注解如何实现的
注解类使用@interface
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {}
jdk1.5定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
@Target 说明了Annotation的访问范围权限
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE用于描述类、接口(包括注解类型) 或enum声明
@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
常用有@Retention(RetentionPolicy.SOURCE) 和 @Retention(RetentionPolicy.RUNTIME)
下面我们来自定义一个注解类
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation {
int id(); //不设置默认值,必填
String className() default ""; //有默认值,可不写
String[] arrays();
}
自定义注解其实很简单,可以直接参照jdk内置注解,当你了解了自定义注解后,再用框架注解时候,思路会不会更加清晰呢?
下面我们来做一个小案例,使用自定义注解完成orm框架映射
比如我们在使用一些orm框架的时候,比如数据库中有这么一些字段
student_id student_name student_scope等,而对应的Entity为:
studentId studentName studentScope
@table("student")
public class student{
@Property("student_id")
private Long studentId;
@Property("student_name")
private String studentName;
@Property("student_scope")
private Double studentScope;
//getter and setter
}
最后通过entity类映射成sql语句 select student_id , student_name , student_scope from student
这是怎么实现实体类与数据库直接的映射的呢?
思路:使用java的反射机制获取每个属性上注解的value,再拼接成sql语句进行DML操作
具体代码实现:
package cn.itcats.system;
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
@Retention(RetentionPolicy.RUNTIME)
@interface table {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@interface property {
String value();
}
@table("student")
class Student {
@property("student_id")
private Long studentId;
@property("student_name")
private String studentName;
@property("student_scope")
private Double studentScope;
}
public class TestORM {
//通过反射获取Student类上的注解,再拼接sql语句
public static void main(String[] args) throws Exception {
Class<?> forName = Class.forName("cn.itcats.system.Student");
//获取Student类中所有字段
Field[] fields = forName.getDeclaredFields();
StringBuilder sb = new StringBuilder("select ");
for(int i = 0 ; i < fields.length ;i++){
Field field = fields[i];
//获取每个属性上的注解
property pro = field.getDeclaredAnnotation(property.class);
sb.append(pro.value());
if(i < fields.length - 1){
sb.append(",");
}
}
//获取类上的注解
table tb = forName.getDeclaredAnnotation(table.class);
sb.append(" from "+ tb.value());
System.out.println(sb.toString());
}
}
打印结果:
select student_id,student_name,student_scope from student