java annotation 必须掌握的特性-永利国际
于2017-04-11 11:14:36 发表在
java知识库
什么是annotation?
annotation翻译为中文即为注解,意思就是提供除了程序本身逻辑外的额外的数据信息。annotation对于标注的代码没有直接的影响,它不可以直接与标注的代码产生交互,但其他组件可以使用这些信息。
annotation信息可以被编译进class文件,也可以保留在java 虚拟机中,从而在运行时可以获取。甚至对于annotation本身也可以加annotation。
那些对象可以加annotation
类,方法,变量,参数,包都可以加annotation。
内置的annotation
@override 重载父类中方法 @deprecated 被标注的方法或类型已不再推荐使用
@suppresswarnings 阻止编译时的警告信息。其需要接收一个string的数组作为参数。 可供使用的参数有:
· unchecked
· path
· serial
· finally
· fallthrough
可以用与其他annotation上的annotation
@retention
确定annotation被保存的生命周期, 需要接收一个enum对象retentionpolicy作为参数。
public enum retentionpolicy {
/**
* annotations are to be discarded by the compiler.
*/
source,
/**
* annotations are to be recorded in the class file by the compiler
* but need not be retained by the vm at run time. this is the default
* behavior.
*/
class,
/**
* annotations are to be recorded in the class file by the compiler and
* retained by the vm at run time, so they may be read reflectively.
*
* @see java.lang.reflect.annotatedelement
*/
runtime
}
@documented 文档化
@target
表示该annotation可以修饰的范围,接收一个enum对象enumtype的数组作为参数。
public enum elementtype {
/** class, interface (including annotation type), or enum declaration */
type,
/** field declaration (includes enum constants) */
field,
/** method declaration */
method,
/** parameter declaration */
parameter,
/** constructor declaration */
constructor,
/** local variable declaration */
local_variable,
/** annotation type declaration */
annotation_type,
/** package declaration */
package
}
@inherited
该annotation可以影响到被标注的类的子类。
自定义annotation
jse5.0以后我们可以自定义annotation。下面就是一个简单的例子。
@retention(retentionpolicy.runtime)
@target(elementtype.method)
public @interface methodannotation {
}
下面的person对象使用了自定义的methodannotation。
public class person {
public void eat() {
system.out.println("eating");
}
@methodannotation
public void walk() {
system.out.print("walking");
}
}
我们可以通过反射获取annotation的信息。
class<person> personclass = person.class;
method[] methods = personclass.getmethods();
for(method method : methods){
if (method.isannotationpresent(methodannotation.class)){
method.invoke(personclass.newinstance());
}
}
输出:
walking
我们也可以给自定义的annotation加方法。
@target(elementtype.type)
public @interface personannotation {
int id() default 1;
string name() default "bowen";
}
下面是对personannotation的使用。
@personannotation(id = 8, name = "john")
public class person {
public void eat() {
system.out.println("eating");
}
@methodannotation
public void walk() {
system.out.print("walking");
}
}
annotation是如何被处理的
当java源代码被编译时,编译器的一个插件annotation处理器则会处理这些annotation。处理器可以产生报告信息,或者创建附加的java源文件或资源。如果annotation本身被加上了rententionpolicy的运行时类,则java编译器则会将annotation的元数据存储到class文件中。然后,java虚拟机或其他的程序可以查找这些元数据并做相应的处理。
当然除了annotation处理器可以处理annotation外,我们也可以使用反射自己来处理annotation。java se 5有一个名为annotatedelement的接口,java的反射对象类class,constructor,field,method以及package都实现了这个接口。这个接口用来表示当前运行在java虚拟机中的被加上了annotation的程序元素。通过这个接口可以使用反射读取annotation。annotatedelement接口可以访问被加上runtime标记的annotation,相应的方法有getannotation,getannotations,isannotationpresent。由于annotation类型被编译和存储在二进制文件中就像class一样,所以可以像查询普通的java对象一样查询这些方法返回的annotation。
annotation的广泛使用
annotation被广泛用于各种框架和库中,下面就列举一些典型的应用.
junit
junit是非常著名的一款单元测试框架,使用junit的时候需要接触大量的annotation。
· @runwith 自定义测试类的runner
· @contextconfiguration 设置spring的applicationcontext
· @dirtiescontext 当执行下一个测试前重新加载applicationcontext.
· @before 调用测试方法前初始化
· @after 调用测试方法后处理
· @test 表明该方法是测试方法
· @ignore 可以加在测试类或测试方法上,忽略运行。
· @beforeclass:在该测试类中的所有测试方法执行前调用,只被调用一次(被标注的方法必须是static)
· @afterclass:在该测试类中的所有的测试方法执行完后调用,只被执行一次(被标注的方法必须是static)
spring
spring 号称配置地狱,annotation也不少。
· @service 给service类加注解
· @repository 给dao类加注解
· @component 给组件类加注解
· @autowired 让spring自动装配bean
· @transactional 配置事物
· @scope 配置对象存活范围
· @controller 给控制器类加注解
· @requestmapping url路径映射
· @pathvariable 将方法参数映射到路径
· @requestparam 将请求参数绑定到方法变量
· @modelattribute 与model绑定
· @sessionattributes 设置到session属性
hibernate
· @entity 修饰entity bean
· @table 将entity类与数据库中的table映射起来
· @column 映射列
· @id 映射id
· @generatedvalue 该字段是自增长的
· @version 版本控制或并发性控制
· @orderby 排序规则
· @lob 大对象标注
hibernate还有大量的关于联合的annotation和继承的annotation,这里就不意义列举了。
jsr 303 – bean validation
jsr 303 – bean validation是一个数据验证的规范,其对java bean的验证主要通过java annotation来实现。
· @null被注释的元素必须为 null
· @notnull被注释的元素必须不为 null
· @asserttrue被注释的元素必须为 [email protected]被注释的元素必须为 [email protected](value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
· @max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
· @decimalmin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
· @decimalmax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
· @size(max, min)被注释的元素的大小必须在指定的范围内
· @digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
· @past被注释的元素必须是一个过去的日期
· @future被注释的元素必须是一个将来的日期
· @pattern(value)被注释的元素必须符合指定的正则表达式
其实还有很多使用了annotaion的framework或library,这里就不一一列举了,希望大家能举一反三,深入了解java中的annotation。