您的位置:首页 > 编程语言 > Java开发

Java Annotation

2016-05-17 11:50 597 查看

注解

意思就是提供除了程序本身逻辑外的额外的数据信息。

Annotation对于标注的代码没有直接的影响,它不可以直接与标注的代码产生交互,但其他组件可以使用这些信息。

Annotation信息可以被编译进class文件,也可以保留在Java 虚拟机中,从而在运行时可以获取。甚至对于Annotation本身也可以加Annotation。

哪些对象可以加Annotation

类,方法,变量,参数,包

内置的Annotation

@Override

重载父类中方法

@Deprecated

被标注的方法或类型已不再推荐使用

@SuppressWarnings

阻止编译时的警告信息。其需要接收一个String的数组作为参数。 可供使用的参数有:

unchecked
path
serial
finally
fallthrough


可以用与其他annotation上的annotation

@Retention

确定Annotation被保存的生命周期, 需要接收一个Enum对象RetentionPolicy作为参数

@Documented

文档化

@Target

表示该Annotation可以修饰的范围,接收一个Enum对象EnumType的数组作为参数

@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文件中。

例如Spring的component:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {

/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";

}


spring的其他注解是被Component注解的,同时也是RententionPolicy,如Controller:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";

}


然后,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的广泛使用

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被注释的元素必须为 true@AssertFalse被注释的元素必须为 false@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min)被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past被注释的元素必须是一个过去的日期
@Future被注释的元素必须是一个将来的日期
@Pattern(value)被注释的元素必须符合指定的正则表达式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: