java notation,java的Anotation机制,以及在WF中的应用

在写代码的时候,总会在类名或者方法名的上面出现@xxx这样的语法,开始的时候我是不会用这种注解符号的,只明白一些注解是起说明作用的如@Overwrite这种,后来接触了Spring之后才明白,这种注解其实有比较大的用处,结合一些博文和自己的实际应用,记录下自己使用的注解和框架中应用注解的实现机制。

1.java中注解的基本使用方式和声明

(1)元注解

1.@Target,

2.@Retention,

3.@Documented,

4.@Inherited

以上几个元注解是为真正我们要实现的注解服务的。

1.@Target 此字段是用于描述注解可以被应用的范围,可被使用的范围有 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)

可以取的值有:

1.CONSTRUCTOR:用于描述构造器

2.FIELD:用于描述域

3.LOCAL_VARIABLE:用于描述局部变量

4.METHOD:用于描述方法

5.PACKAGE:用于描述包

6.PARAMETER:用于描述参数

7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

Target可以被添加到目标注解的头部,表示目标注解的应用范围。

2.@Retention定义了该Annotation被保留的时间长短:简单来说就是目标注解的作用范围;

可以取的值为:

1.SOURCE:在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)

3.RUNTIME:在运行时有效(即运行时保留)

一般都是用于RUNTIME

3.@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API

用于声明当前修饰的注解能不能生成在java doc中,此参数是没有成员的。

4.@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

此元注解我用到的不多,就不多说了

(2).自定义注解的实现

自定义注解其实是基于元注解去实现的一种注解,通常主要用于拦截器或者成员的声明等,使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

下面自定义实现一个java的Annotation:

首先定义一个Annotation:

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 ColorAnnotation {

public String value() default "red";//默认值

}

定义一个使用此注解的类:

public class ColorTest {

@ColorAnnotation("yellow")

public String color;

}

只定义和使用注解是远远达不到目的的,接下来我们还需要对注解进行解析

Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素,该接口主要有如下几个实现类:

Class:类定义

Constructor:构造器定义

Field:累的成员变量定义

Method:类的方法定义

Package:类的包定义

java.lang.reflect 包下主要包含一些实现反射功能的工具类,实际上,java.lang.reflect 包所有提供的反射API扩充了读取运行时Annotation信息的能力。当一个Annotation类型被定义为运行时的Annotation后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。

AnnotatedElement 接口是所有程序元素(Class、Method和Constructor)的父接口,所以程序通过反射获取了某个类的AnnotatedElement对象之后,程序就可以调用该对象的如下四个个方法来访问Annotation信息:

方法1: T getAnnotation(Class annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。

方法2:Annotation[] getAnnotations():返回该程序元素上存在的所有注解。

方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.

方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

接下来是对注解进行解析:

import java.lang.reflect.Field;

public class ColorPaser {

public static void parse(Class> clazz){

Field fields[] = clazz.getDeclaredFields();

for(Field f : fields){

if(f.isAnnotationPresent(ColorAnnotation.class)){

ColorAnnotation color = f.getAnnotation(ColorAnnotation.class);

String colorStr = color.value();

System.out.println(colorStr);

}

}

}

public static void main(String args[]){

ColorPaser.parse(ColorTest.class);

}

}

这样就实现了对注解的解析处理。当然实际应用中这种注解的解析模式可以应用到拦截器上面,我们现在用的框架就是自己定义实现了一个通过注解进行的拦截器。然后在Filter中进行解析请求 映射Controller解析到对应的注解进行对请求的拦截。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值