java注解的实质,何为注解
注解就是贴标签
(1)注解的作用
1,生成文档。如常用的 @param
2,跟踪代码依赖性,实现替代文件的功能。在 spring 中,主要是减少配置。
3,编译时进行格式检查。如常用的 @override
(2)注解的分类
1)按照运行机制划分:
【源码注解→编译时注解→运行时注解】
源码注解:只在源码中存在,编译成.class 文件就不存在了。
编译时注解:在源码和.class 文件中都存在。像前面的 @Override、@Deprecated、@SuppressWarnings,他们都属于编译时注解。
运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解。像 @Autowired 自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。
2)按照来源划分:
【来自 JDK 的注解——来自第三方的注解——自定义注解】
3)元注解:
元注解是给注解进行注解,可以理解为注解的注解就是元注解。
(3)java 中常见的注解
1,JDK 的注解
@override 标记该方法为覆盖方法
@Deprecated 标记该方法已经过时
@SuppressWarning() 表示忽略警告
2,java 第三方注解
Spring 的注解
@Autowired 可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作
@Service 用于标注业务层组件
@Controller 用于标注控制层组件(如 struts 中的 action)
@Repository 用于标注数据访问组件,即 DAO 组件
@Component 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
Mybatis 的注解
@InserProvider 注解为增加
@UpdateProvider 注解为更新
@Options 设置缓存时间
Ps:常用增删改查:@InsertProvider,@DeleteProvider@UpdateProvider 和 @SelectProvider
3,元注解
四个元注解分别是:
@Target
@Retention,
@Documented,
@Inherited
元注解是 java API 提供,是专门用来定义注解的注解,其作用分别如下:
@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括:
ElemenetType.CONSTRUCTOR---------------------------- 构造器声明
ElemenetType.FIELD -------------------------------------- 域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE------------------------- 局部变量声明
ElemenetType.METHOD ---------------------------------- 方法声明
ElemenetType.PACKAGE --------------------------------- 包声明
ElemenetType.PARAMETER ------------------------------ 参数声明
ElemenetType.TYPE--------------------------------------- 类,接口(包括注解类型)或 enum 声明
@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括:
RetentionPolicy.SOURCE --------------------------------- 注解将被编译器丢弃
RetentionPolicy.CLASS ----------------------------------- 注解在 class 文件中可用,但会被 VM 丢弃
RetentionPolicy.RUNTIME VM------- 将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被 javadoc 工具提取成文档。在 doc 文档中的内容会因为此注解的信息内容不同而不同。相当与 @see,@param 等。
@Inherited 允许子类继承父类中的注解。
4,自定义注解
例子:
定义:
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented public @interface Description {
String desc();
String author();
int age() default 18;
}
测试:
@Description(desc="i am Color",author="boy",age=18)
public String Color() {
return "red";
}
因为我们前面定义的作用域是在方法和类接口上,所以这个注解在 Color() 方法上使用是没问题的
使用自定义注解:
使用注解的语法:
@< 注解名 >(< 成员名 1>=< 成员值 1>,< 成员名 1>=< 成员值 1>,...)
案例:
@Description(desc="i am Color",author="boy",age=18)
public String Color() {
return "red";
}
这里的 Description 是我们刚才在自定义注解语法要求里面定义的注解噢,然后我们可以给它的每一个成员变量赋值,注意数据类型。值得注意的是,因为我们前面定义的作用域是在方法和类接口上,所以这个注解在 Color() 方法上使用是没问题的。
解析注解
概念:
通过反射获取类 、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | 1 、创建 @Table 注解 package person.lb.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 表名 * @author nobounds * */ @Target ({ElementType.TYPE}) @Retention (RetentionPolicy.RUNTIME) public @interface Table { String value() default "" ; } 2 、创建 @Column 注解: package person.lb.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 字段 * @author nobounds * */ @Target (ElementType.FIELD) @Retention (RetentionPolicy.RUNTIME) public @interface Column { String name() default "" ; String dataType() default "varchar(20)" ; String comment() default "" ; } 3 、创建实体类Users: package person.lb.annotation; @Table ( "users" ) public class Users { @Column (name= "ID" , dataType= "int" ) private int id; @Column (comment= "用户名" ) private String userName; @Column (name= "pwd" , comment= "密码" ) private String password; @Column (dataType= "varchar(25)" , comment= "邮箱" ) private String email; public String getUserName() { return userName; } public void setUserName(String userName) { this .userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this .password = password; } public String getEmail() { return email; } public void setEmail(String email) { this .email = email; } } 4 、创建注解处理器AnnotationHandler: package person.lb.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.Field; public class AnnotationHandler { public static void main(String[] args) { StringBuilder sql = new StringBuilder( "CREATE TABLE " ); try { Class clazz = Class.forName( "person.lb.annotation.Users" ); //获取Users类上的Table注解 Table tableAnnotation = (Table) clazz.getAnnotation(Table. class ); //获取表名 String tableName = tableAnnotation.value().toUpperCase(); if ( "" .equals(tableName)) { tableName = clazz.getName().toUpperCase(); } sql.append(tableName); sql.append( " ( \n" ); //获取类中的所有字段 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { //获取字段上的所有注解 Annotation[] fieldAnnotations = field.getAnnotations(); if (fieldAnnotations.length > 0 ) { //遍历注解 for (Annotation fieldAnnotation : fieldAnnotations) { //如果是@Field注解,那么进行处理 if (fieldAnnotation instanceof Column) { //获取字段名 String columnName = ((Column) fieldAnnotation).name().toUpperCase(); if ( "" .equals(columnName)) { columnName = field.getName().toUpperCase(); } //获取数据类型 String dataType = ((Column) fieldAnnotation).dataType().toUpperCase(); //获取注释 String comment = ((Column) fieldAnnotation).comment(); if ( "" .equals(comment)) { sql.append(columnName + "\t" + dataType + ",\n" ); } else { sql.append(columnName + "\t" + dataType + " COMMENT '" + comment + "',\n" ); } } } } } sql.append( " ) " ); System.out.println( "生成的sql语句为:\n" + sql.toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } |
结果:
1 2 3 4 5 6 7 | 生成的sql语句为: CREATE TABLE USERS ( ID INT, USERNAME VARCHAR( 20 ) COMMENT '用户名' , PWD VARCHAR( 20 ) COMMENT '密码' , EMAIL VARCHAR( 25 ) COMMENT '邮箱' , ) |