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)被注释的元素必须符合指定的正则表达式
相关文章推荐
- Java正则表达式详解(三)
- Java线程池详解
- spring mvc 4+ @ResponseBody 中文乱码
- [Java] 实验11
- Spring之框架初探
- MyEclipse10安装SVN插件
- IT十八掌作业_java基础第九天_多线程、自动拆装箱
- Java多线程
- java 并发
- 分布式自增长ID(Twitter的 Snowflake JAVA实现方案 )
- java下载文件
- JAVA中获取可用的CPU数量
- java学习个人笔记---构造器的陷阱
- 如何从Eclipse导入github上的项目源码
- java线程创建和启动
- spring-boot系列:初试spring-boot
- java多线程实现方式(遗忘....)
- Java 利用commons-configuration.jar 动态修改配置文件(.properties)
- JavaWeb开发(6)--servlet(2)
- SpringMVC Interceptor中通过Request获取Controller方法