什么是注解?
注解就是代码的元数据,他们包含了代码自身的信息。那么什么又是元数据?元数据是指描述数据的数据,描述数据属性的信息。
注解可以被用在包,类,方法,变量,参数上。自Java8起,有一种注解几乎可以被放在代码的任何位置,叫做类型注解。
注解的使用场景
- 编译检查
- 文档
- 代码生成 根据注解生成代码或者xml。 如JAXB
- 运行时处理 如junit, orm,spring等
自定义注解
@Target
用于描述注解的使用范围
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention
用于描述注解的生命周期
- SOURCE:在源文件中有效(即源文件保留)
- CLASS:在class文件中有效(即class保留)
- RUNTIME:在运行时有效(即运行时保留)
@Documented
Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API
@Inherited
@Inherited表示是可以被继承的, 如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类
示例:
target class:
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Documented
@Inherited
public @interface CustomAnnotationClass implements CustomAnnotationMethod {
public String author() default "danibuiza";
public String date();
}
使用:
@CustomAnnotationClass( date = "2014-05-05" )
public class AnnotatedClass
{
}
target method:
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.METHOD )
public @interface CustomAnnotationMethod
{
public String author() default "danibuiza";
public String date();
public String description();
}
使用:
@CustomAnnotationMethod( author = "friend of mine", date = "2014-06-05", description = "annotated method" )
public String annotatedMethodFromAFriend()
{
return "nothing niente";
}
target 属性:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomAnnotationField{
public enum Color{ BULE,RED,GREEN};
Color color() default Color.GREEN;
}
使用:
@CustomAnnotationField(color=Color.RED)
private String appleColor;
注解的处理
java api中提供了通过反射来获取注解.
- getAnnotations(): 返回该元素的所有注解,包括没有显式定义该元素上的注解。
- isAnnotationPresent(annotation): 检查传入的注解是否存在于当前元素。
- getAnnotation(class): 按照传入的参数获取指定类型的注解。返回null说明当前元素不带有此注解。
示例:
Class<AnnotatedClass> clazz= AnnotatedClass.class;
// 判断 该类 是否存在注解
if( clazz.isAnnotationPresent( CustomAnnotationClass.class ) )
{
// 获取类注解
Annotation annotation = clazz.getAnnotation( CustomAnnotationClass.class );
System.out.println( annotation );
}
// 获取method 注解
for( Method method : clazz.getDeclaredMethods() )
{
//判断方法是否存在注解
if( method.isAnnotationPresent( CustomAnnotationMethod.class ) )
{
Annotation annotation = method.getAnnotation( CustomAnnotationMethod.class );
System.out.println( annotation );
}
}
Field[] fields = clazz.getDeclaredFields();
for(Field field :fields ){
if(field.isAnnotationPresent(CustomAnnotationField.class)){
CustomAnnotationField field = (FruitName) field.getAnnotation(CustomAnnotationField.class);
System.out.println(field );
}
}
另外一个实例, 结合动态代理进行权限控制:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredRoles {
String[] value();
}
public class AccessInvocationHandler<T> implements InvocationHandler {
final T accessObj;
public AccessInvocationHandler(T accessObj) {
this.accessObj = accessObj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RequiredRoles annotation = method.getAnnotation(RequiredRoles.class); //通过反射API获取注解
if (annotation != null) {
String[] roles = annotation.value();
String role = AccessControl.getCurrentRole();
if (!Arrays.asList(roles).contains(role)) {
throw new AccessControlException("The user is not allowed to invoke this method.");
}
}
return method.invoke(accessObj, args);
}
}
参考:
http://www.importnew.com/14227.html
http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
http://www.infoq.com/cn/articles/cf-java-annotation
扩展: 主要是AbstractProcessor 的使用技巧
http://blog.csdn.net/lmj623565791/article/details/43452969
http://blog.csdn.net/lmj623565791/article/details/39275847
http://www.cnblogs.com/avenwu/p/4173899.html
网友评论