1. 什么是注解?
Jdk1.5新增新技术,注解。很多框架为了简化代码,都会提供有些注解。可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件。
注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。
注解分类:内置注解(也成为元注解 jdk 自带注解)、自定义注解(Spring框架)
2. 什么是内置注解
比如
- (1) @SuppressWarnings 再程序前面加上可以在javac编译中去除警告–阶段是SOURCE
- (2) @Deprecated 带有标记的包,方法,字段说明其过时----阶段是SOURCE
- (3)@Overricle 打上这个标记说明该方法是将父类的方法重写–阶段是SOURCE
@Overricle 案例演示
@Override
public String toString() {
return null;
}
@ Deprecated案例演示
new Date().parse("");
@ SuppressWarnings 案例演示
@SuppressWarnings({ "all" })
public void save() {
java.util.List list = new ArrayList();
}
3. 实现自定义注解
元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
@Target
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention
表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
@Documented
@Inherited
代码:
使用@interface 定义注解。
@Target(value = { ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface OneAnnotation {
int beanId() default 0;
String className() default "";
String[]arrays();
}
使用:
@OneAnnotation(beanId = 123, className = "className", arrays = { "111", "222" })
public void add() {
}
4. 自定义注解实现ORM框架映射
完成案例,ORM框架实体类与表字段不一致,底层生成sql语句原理。
自定义表映射注解
/**
* @Auther: 洺润Star
* @Date: 2020/3/1 15:10
* @Description:自定义表映射注解
*/
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Test02SetTable {
String value();//对应数据库的表名称
}
自定义字段属性映射注解
/**
* @Auther: 洺润Star
* @Date: 2020/3/1 15:13
* @Description:自定义字段属性
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Test02SetProperty {
int length();
String name();//对应字段名称
}
定义实体类使用上面定义的注解
/**
* @Auther: 洺润Star
* @Date: 2020/3/1 15:15
* @Description:
*/
@Test02SetTable("user")
public class Test02User {
@Test02SetProperty(name = "it_id", length = 10)
private String id;
@Test02SetProperty(name = "it_name", length = 10)
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用反射获取类中属性上定义的注解,再获取注解中的值,最终完成映射输出sql语句
/**
* @Auther: 洺润Star
* @Date: 2020/3/1 15:18
* @Description:输出sql语句
*/
public class Test02AnnotationMain {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass = Class.forName("annotation.Test02User");
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("select");
//获取所有属性
Field[] declaredFields = aClass.getDeclaredFields();
for (int i = 0; i<declaredFields.length;i++){
Field field = declaredFields[i];
Test02SetProperty declaredAnnotation = field.getDeclaredAnnotation(Test02SetProperty.class);
String name = declaredAnnotation.name();
stringBuilder.append(" "+name);
if (i<declaredFields.length-1){
stringBuilder.append(",");
}
}
Test02SetTable test02SetTable = aClass.getDeclaredAnnotation(Test02SetTable.class);
// 表的名称
String tableName = test02SetTable.value();
stringBuilder.append(" from " + tableName);
System.out.println(stringBuilder.toString());
}
}