只是讲述一下自定注解的大概流程,具体例子并不完整。
自定义注解可以理解为三个步骤
1、定义自己的注解类。
这个步骤可以理解为是为了方便用户使用自己的注解(类似于JSP model1中的JSP)
2、定义工具类。
工具类是用来实现注解的功能的。这个注解有什么功能需要有一个对应的工具类来实现。(类似于JSP model1中的Javabean)。
工具类往往包含一个返回自身的静态方法,这个静态方法接收一个class、method或filed类对象,然后处理这个对象中包含的注解信息。
3、注解处理器类
注解类有了,处理注解的工具类有了,那么这时候就需要一个注解处理器类。这个类用来给工具类提供那些使用了注解的Class对象。比如:扫描某个路径下的所有class文件,将这些class文件转换成class对象,传递给工具类。
可以理解为数据源。(类似于JSP model1中与javabean交互的数据库)
一、定义自己的注解,如(以下是实体映射注解的一部分:实体类中根据成员变量(即对应数据表中的字段)的注解):
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column{
public String value() default "";//字段类型
public boolean nullable() default true;//字段是否可以为null
public int length() default -1;//字段长度限制
}
二、相关工具类
上面的注解的一个使用例子是@Column(value=“..”,nullable=true,length=32);
那么这时候我们需要定义一个类,这个类能够识别出这个注解,然后实现相应的功能,比如根据这个注解生成相应的sql语句。
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class ColumnInfo {
private String columnName;
private Class<?> type;
private boolean isID = false;
private boolean nullable = true;
private int length = 32;
private boolean needPersist=false;//该字段是否需要保存到数据库中
public ColumnInfo parse(Field field){ //利用反射中的field类,转换成ColumnInfo对像
this.columnName = field.getName();
this.type = field.getType();
Annotation[] annotations = field.getAnnotations();
for(Annotation annotation:annotations){
if(annotation.annotationType().equals(Column.class)) {
this.needPersist = true;
Column column = (Column) annotation;
if (!column.value().equals("")) {
this.columnName = column.value();
this.nullable = column.nullable();
if (column.length() != -1) {
this.length = column.length();
} else if (annotation.annotationType().equals(ID.class)) {
this.needPersist = true;
ID id = (ID) annotation;
this.isID = true;
if (!id.value().equals("")) {
this.columnName = id.value();
}
}
}
}
}
if(this.needPersist) return this;
return null;
}
//输出sql语句
public String toString(){
StringBuilder sql = new StringBuilder(columnName);
if(this.type.equals(String.class)){
sql.append(" "+"VARCHAR("+this.length+")");
}else if(this.type.equals(Integer.class)){
sql.append(" "+"INT");
}
if(!this.nullable){
sql.append(" "+"NOT NULL");
}
sql.append(";");
return sql.toString();
}
}
三、注解处理器
这个时候我们已经有了自己定义的注解、处理注解的工具类,那么接下来我们还需要一个注解处理器,这个注解处理器能够扫描到我们使用了注解的类文件,将类文件转换成Class对象,将Class对象传递给工具类,工具类将根据这个Class对象获取到相应的注解信息与类信息,进而实现我们自定义注解的功能。
import java.io.File;
import java.util.List;
import java.util.Scanner;
public class TableProcessor implements IProcessor{
public String process(String url){
List<File> classFiles = Scanner.getClassFiles();//读取class文件
for(File file:classFiles){
Class<?> clazz = ClassFileLoader.loadClass(file);//将文件流转换成class对象
TableInfo table = TableInfo.parse(clazz);
if(table!=null){
sql.append(table.toString());
}
}
return sql.toString();
}
}
四、如何使用注解:
1、定义一个使用注解的类
class Person{
@Column(value = "",nullable = true,length = 10)
private String name;
}
2、定义一个main方法
public static void main(String[] args){
TableProcessor processor = new TableProcessor();
String sql = processor.process("...");
System.out.println(sql);
}