文档章节

自定义注解Annotation的使用

boonya
 boonya
发布于 2015/04/17 07:07
字数 1442
阅读 3283
收藏 3

1.       前言

JDK1.5以后,推出了注解新特性。注解的推出其实最主要的目的是为了让广大的用户认知EJB3.0,因为EJB2.X广受大多数开发者的诟骂和质疑。为了减少配置、让注解替代配置。有了注解,我们以前看似一般的、普通的JavaBean就有了活力,有了内涵,有了新的契机。配合SunJPA规范,EJB3.X又再次在企业级开发中大放异彩,让很多开发者赞不绝口。也许是无心插柳,这种“零配置”思维也影响着Java其他的开源项目——像StrutsSpringHibernate(也就是咱们耳熟能详的SSH)不都是具有“零配置”支持嘛!Java现在也是往动态、敏捷的方向发展着。有可能将来配置文件越来越少、规范、约定、注解代替了繁琐的配置信息。而XML估计会回归原始的使命——数据传输与数据交换。

2.       自定义注解

至于已有的注解,比如:JPAEJBSpring零配置等等怎么使用相信各位读者都能掌握,这里主要是说如何自定义自己的注解,自己使用自定义的注解。

我们先用一个简单的例子来看

package annotation;

 

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

 

/**

 * 注解

 *

 * @author  Administrator

 */

@Retention(RetentionPolicy.RUNTIME)

public @interface  Test {

 

    String isAop() default "false";

 

}

用关键字@interface 定义一个注解标记,使用@interface 关键字实际上的意思就是该接口继承自java.lang.annotation.Annotation接口。

String isAop() default "false";

这句话代表的意思就是在Test注解中可以含有属性名为isAop,此属性的类型是字符串类型。客户端使用的时候可以根据需要自己指定相关的属性值。如果客户端不指定值,默认值是false

@Retention(RetentionPolicy.RUNTIME)

这句话代表着将使用该注解类的信息值保持到真正的客户端运行时环境。

下面我们就来看看客户端的使用

package use;

 

import annotation.Test;

import annotation.TestImpl.TestProcess;

 

@Test(isAop = "true")

public class UseTest {

 

    /**

     * @param args

     * @throws ClassNotFoundException

     */

    public static void main(String[] args) throws ClassNotFoundException {

 

       TestProcess.process("use.UseTest");

 

    }

 

}

在客户端调用中在类UseTest上使用了@Test(isAop = "true")注解。仅仅定义了注解就像《三国杀》里,刘备是主公,他有“激将”的主公计,下了个命令:“蜀将何在?”,刘备的这句话太抽象了,蜀将相当于一个注解。在场的所有蜀将就像加了此注解的类,都会受到这句话的影响。具体替不替刘备出杀,~~~~个人表现不同(得先看看自己的身份啊)反贼的表现是:“这个真没有”;忠臣的表现是,先看看手上有杀吗?有,出击吧!没有就说:“这个……真没有!”;内奸的反应是:“唉,先保命还是装一装忠臣?比较纠结!”。这里的身份就好像是注解的属性的不同值。具体的处理就相当于针对注解的处理实现类。注解的具体实现类就是处理注解的业务逻辑,它需要Java的反射机制来处理客户目标类的具体注解,我们就来看看这个注解处理实现类。

package annotation.TestImpl;

 

import java.lang.annotation.Annotation;

 

public class TestProcess {

 

    public static void process(String str) throws ClassNotFoundException {

 

       Class clazz = Class.forName(str);

 

       Annotation[] annotations = clazz.getAnnotations();

 

       for (Annotation annotation : annotations) {

           System.out.println(annotation);

       }

    }

 

}

以上的处理逻辑很简单,就是根据一个字符串类名找到类。获得类的所有注解,所有注解是一个对象数组。遍历注解数组,输出相关注解信息。运行以上的程序结果如下

@annotation.Test(isAop=true)

如果我们使用注解的客户端代码替换一下

@Test

public class UseTest {

<span courier="" new";="" mso-hansi-font-family:"courier="" new";mso-bidi-font-family:"courier="" mso-font-kerning:0;"="" style="line-height: 23.333332061767578px;font-size: 13px;font-family: 宋体">……………………

}

对于注解的isAop并不特别指定。运行效果如下

@annotation.Test(isAop=false)

可以看到使用的是默认值false。如果注解中Annotation并没有指定默认值,而在客户端使用中也没指定值,那么不会通过编译。

@Retention(RetentionPolicy.XXXXXX)上面说到了是保留注解的有效期。

//会将注解保留到编译后的class中,加载类的时候不生效

@Retention(RetentionPolicy.CLASS)

//仅仅在代码保留,编译后的class不会保留

@Retention(RetentionPolicy.SOURCE)

//在编译后的class会有,通过反射也会获得注解信息

@Retention(RetentionPolicy.RUNTIME)

比如Override注解的源码

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.SOURCE)

public @interface Override {

}

因为复写在使用者使用的时候就可以看出来,所以没必要保留到运行期。

比如SuppressWarnings注解的源码

 

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})

@Retention(RetentionPolicy.SOURCE)

public @interface SuppressWarnings {

    String[] value();

}

以上的不提示警告的注解也是在编译一个类前检查即可。

以上还使用了@Target注解,它代表着注解的修饰范围,类型是java.lang.annotation.ElementType枚举类型。

public enum ElementType {

    TYPE,//可以修饰成员变量

    METHOD,//可以修饰参数

    CONSTRUCTOR,//可以修饰局部变量

    ANNOTATION_TYPE,// <span courier="" new";="" mso-hansi-font-family:"courier="" new";mso-bidi-font-family:"courier="" color:black;mso-font-kerning:0;"="" style="line-height: 23.333332061767578px;font-size: 13px;font-family: 宋体">可以修饰Annotation

    PACKAGE//可以修饰包

}

Deprecated源码

@Documented

@Retention(RetentionPolicy.RUNTIME)

public @interface Deprecated {

}

Deprecated代表已过时的意思,这是一个保持到运行期的注解,在运行期可以通过反射获取此注解。这里还使用了@Documented这个元注解。它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。

还有一个注解就是Inherited,如果使用了该标记,那么使用该注解的子类也会继承该注解的特性。



本文转载自:http://blog.163.com/fang_lianggo@126/blog/static/36639740201211611541598/

共有 人打赏支持
boonya
粉丝 73
博文 214
码字总数 43922
作品 0
成都
高级程序员
私信 提问
Java注解(Annotation)详解

Java注解(Annotation)详解 1.Annotation的概念 An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may......

幻海流心
05/23
0
0
注解-你可能需要知道这些

在日常的开发工作中,尤其是在使用一些比较受欢迎的开源框架时,我们不可避免的都使用到了注解(Annotation),注解的使用范围也越来越广,而且在使用了注解后,我们的代码看起来也更简洁了。...

24K男
2017/09/28
0
0
关于注解那些事情

最近突然看到其他人写的代码实现了自定义注解,好奇心被激活了。所以查了很多资料,然后写了一个简单的自定义注解,在写的过程中我发现了调用自定义注解的麻烦,所以我希望把我的代码贴出来,...

laohng1995
01/15
0
0
java中的注解(Annotation)

简介 注解,java中提供了一种原程序中的元素关联任何信息、任何元素的途径的途径和方法。 注解是那些插入到源代码中使用其他工具可以对其进行处理的标签。注解不会改变程序的编译方式。java编...

林湾村龙猫
2016/11/28
8
0
java.lang.annotation包类的浅析

1、先看一下annotation包下的类,作者的jdk是1.6版本。 Annotation是接口,the common interface extended by all annotation types,意思就就是说Annotation是所有注解类型的父类型,个人感觉...

杨树兴
2014/04/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

AutoCAD_系统变量

https://baike.sogou.com/v53561514.htm?fromTitle=cad%E5%8F%98%E9%87%8F lunits 设置线性单位。1 科学 2 小数 3 工程 4 建筑 5 分数 6 windesk...

一个小妞
14分钟前
2
0
点播转码相关常见问题及排查方式

概述: 点播转码目前涉及用户上传自动触发转码、通过SubmitTranscodeJobs接口触发转码等方式,会出现用户转码失败的情况,这当中有用户源片的问题、也有用户设置转码参数的原因以及相关资源性...

阿里云云栖社区
16分钟前
1
0
图片base64预览及上传PHP处理

1、前端代码 <div id="img"/> <input type="file" id="img-select"/> <input type='button' id='submit'/> var newUrl; function imgPreview() {//将图片转成base64,实现预览效果 var file......

葬-花
17分钟前
0
0
Iris框架

1、安装iris: $ go get -u github.com/kataras/iris 2、golang iris web项目热重启 # 安装rizla包 $ go get -u github.com/kataras/rizla # 热重启方式启动iris项目 $ rizla main.go......

Liens
25分钟前
3
0
初探sentinel实践思考

简单说下, sentinel的优势: 友好的控制面板,支持实时监控 多种限流。支持QPS限流,线程数限流,多种限流策略,如:直接拒绝,匀速模式(漏斗),冷启动(如设置限制1000,延迟10秒,那第一...

爱吃大肉包
27分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部