转自:http://snkcxy.iteye.com/blog/1821512
1.annotation类型(叫法有很多种,官方API这样定义:Annotation Types)
- @Documented:被这个类型标识(修饰)的annotation 将会被javadoc或其他文档工具提取
- @Inherited:表示具有继承性,被这个类型标识(修饰)的annotation 它的子类将会自动被它标识(修饰)
- @Retention:annotation将被保留多长时间
- @Target:指定被标识(修饰)的annotation 能用于修饰程序的哪些部分(类、方法、成员变量等)
2.两个枚举类ElementType和RetentionPolicy
-
ElementType:枚举了@Target类型的value值
ElementType.FIELD:用于修饰成员变量
ElementType.METHOD:用于修饰方法
当然不止这些,更加详细的可查api或者ide下自己试试 -
RetentionPolicy:枚举了@Retention的value值
RetentionPolicy.RUNTIME:直到运行时候都会保留的annotation
RetentionPolicy.CLASS:记录在class文件中,但是运行时不会被保留
RetentionPolicy.SOURCE:保留在源码中,会被编译器丢弃
3.如何自己定义一个annotation(具体见例子中的注释)
- 使用@interface关键字,和定义类,定义接口类似
@interface MyAnnotation{} 这样一个最简单的annotation就定义好了。 - 定义元数据,暂时可以理解为成员变量
- 编写一个annotation处理器(通过反射获取annotation信息或者通过实现接口,继承抽象类来完成)
4.例子1简单讲解
-
我们要做什么?
原始的Aclass 没有日志,我们现在要给一些方法加上日志的功能(有点AOP思想) -
目录结构:
a.Aclass:一个演示目标类,里面提供了4个方法,有2个打上了@CxyLog标记,当使用annotation处理器去处理的时候会看到打上标记的会输出日志语句。
b.(不带元数据的)@CxyLog:加上这个标记的就自动加上打印日志功能
c.CxyLogAp:annotation处理器,这里主要处理@CxyLog -
说明:
1.一个很简单的例子,意在演示:如何创建一个annotation和annotation处理器,并让其工作起来
2.本例借助的是AOP的概念,但是绝对不是实现AOP。所以程序运行时并不是一个一个方法去调用。
3.实现AOP需要涉及接口、反射、动态代理、aop概念等等知识,这里只是单纯的做annotation的介绍。
5.例子2简单讲解
-
我们要做什么?
根据权限动态装配对应的类(bo) -
目录结构
a.CxyAction:测试目标类,提供了两个不同权限的方法
b.CxyBo:一个接口为了演示动态装配而生
c.CxyCommonBo:普通权限的bo,实现CxyBo接口
d.CxyAdvancedBo:高级权限的bo,实现CxyBo接口
e.@CxyAuthority:标记方法的权限及对应权限的实现类
f.CxyAuthorityAp:@CxyAuthority的处理器 -
说明:
1.本例演示了一个带元数据的annotation,并根据元数据信息(authority和boName)来动态装配bo。
2.本例仅仅是演示annotation用法,实际工作中并不会这样去控制权限或者装配bo。
3.authority和boName的存在貌似有些重复,那是因为这个例子里authority和boName是一对一的关系,如果是多对多的关系,这两个元信息就不会觉得是重复的了。
6.总结一下 看看我们干了什么?
- 其实就是给程序的某个部位(类、成员变量、方法等)打了一个标记,这个标记其实没什么大不了(不复杂不深奥顶多就是一个程序注释)
- 但是如果你自己写了一个annotation处理器去处理这个标记的话,那么它能为你做到很多很多。
说明:本例只是阐述annotation的详细用法,我会尽快出一个较为有意义的实例应用文章。
例一:
- package com.cxy.annotation;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- import java.lang.reflect.Method;
- /**
- * @author cxy
- */
- public class AnnotationDetailTest
- {
- public static void main(String[] args) throws Exception
- {
- CxyLogAp.Processor(Aclass.class);
- }
- }
- /**
- * 一个测试用的类,这个类的method1和method3被@CxyLog标记
- */
- class Aclass
- {
- @CxyLog
- public static void method1(){System.out.println("method1执行");}
- public static void method2(){System.out.println("method2执行");}
- @CxyLog
- public static void method3(){System.out.println("method3执行");}
- public static void method4(){System.out.println("method4执行");}
- }
- /**
- * 一个简单的annotation,打上这个标记的我们就给这个方法加入日志打印功能
- * 1.@Retention(RetentionPolicy.RUNTIME) 解释:保留注释到程序运行
- * 2.@Target(ElementType.METHOD) 解释:这个annotation是标记在方法上的
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- @interface CxyLog{}
- /**这个类是@CxyLog的annotation处理器
- */
- class CxyLogAp
- {
- //处理器 处理@CxyLog标记
- public static void Processor(Class clz) throws Exception
- {
- for(Method m:clz.getMethods())
- {
- //如果当前访问的方法打上了@CxyLog标识,那么就加入打印语句
- if(m.isAnnotationPresent(CxyLog.class))
- {
- m.invoke(null);
- System.out.println("日志:"+clz+"."+m.getName()+"执行!");
- }else
- {
- //因为他会执行所有的方法,包括父类的很多方法,所以这里我们限定一下只做我们定义的method开头的方法
- if(m.getName().contains("method"))
- {
- m.invoke(null);
- }
- }
- }
- }
- }
package com.cxy.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; /** * @author cxy */ public class AnnotationDetailTest { public static void main(String[] args) throws Exception { CxyLogAp.Processor(Aclass.class); } } /** * 一个测试用的类,这个类的method1和method3被@CxyLog标记 */ class Aclass { @CxyLog public static void method1(){System.out.println("method1执行");} public static void method2(){System.out.println("method2执行");} @CxyLog public static void method3(){System.out.println("method3执行");} public static void method4(){System.out.println("method4执行");} } /** * 一个简单的annotation,打上这个标记的我们就给这个方法加入日志打印功能 * 1.@Retention(RetentionPolicy.RUNTIME) 解释:保留注释到程序运行 * 2.@Target(ElementType.METHOD) 解释:这个annotation是标记在方法上的 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface CxyLog{} /**这个类是@CxyLog的annotation处理器 */ class CxyLogAp { //处理器 处理@CxyLog标记 public static void Processor(Class clz) throws Exception { for(Method m:clz.getMethods()) { //如果当前访问的方法打上了@CxyLog标识,那么就加入打印语句 if(m.isAnnotationPresent(CxyLog.class)) { m.invoke(null); System.out.println("日志:"+clz+"."+m.getName()+"执行!"); }else { //因为他会执行所有的方法,包括父类的很多方法,所以这里我们限定一下只做我们定义的method开头的方法 if(m.getName().contains("method")) { m.invoke(null); } } } } }
结果图:
例二:
- package com.cxy.annotation;
- import java.lang.annotation.Annotation;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
- import java.lang.reflect.Method;
- /**
- * @author cxy
- */
- public class AnnotationDetailTest1
- {
- public static void main(String[] args) throws Exception
- {
- CxyAction.commonAuthoritymethod();
- CxyAction.advanceAuthoritymethod();
- System.out.println("=============================");
- //以下面的两种方式执行这两个方法
- CxyAuthorityAp.Processor(CxyAction.class, "commonAuthoritymethod");
- System.out.println("------------------------------");
- CxyAuthorityAp.Processor(CxyAction.class, "advanceAuthoritymethod");
- }
- }
- /** 测试目标类,提供了两个不同权限的方法
- */
- class CxyAction
- {
- public static CxyBo bo=new CxyCommonBo(); //初始时候装配的是普通权限的bo
- //普通权限就能访问的方法
- @CxyAuthority(authority="c",boName=CxyCommonBo.class)
- public static void commonAuthoritymethod()
- {
- bo.doSomething();
- }
- //高级权限能访问的方法
- @CxyAuthority(authority="a",boName=CxyAdvancedBo.class)
- public static void advanceAuthoritymethod()
- {
- bo.doSomething();
- }
- }
- /** 一个接口为了演示动态装配而生
- */
- interface CxyBo
- {
- public void doSomething();
- }
- /** 普通权限的bo
- */
- class CxyCommonBo implements CxyBo
- {
- //普通业务逻辑
- @Override
- public void doSomething()
- {
- System.out.println("执行:普通权限处理方法");
- }
- }
- /** 高级权限的bo
- */
- class CxyAdvancedBo implements CxyBo
- {
- //高级业务逻辑
- @Override
- public void doSomething()
- {
- System.out.println("执行:高级权限处理方法");
- }
- }
- //权限annotation,根据这个标记的authority值来判断装配哪个业务逻辑类
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- @interface CxyAuthority
- {
- String authority(); //代表权限
- Class boName(); //代表这个权限用什么bo去处理
- }
- /**这个类是@CxyAuthority的annotation处理器
- */
- class CxyAuthorityAp
- {
- //处理器 处理@CxyAuthority标记
- public static void Processor(Class clz,String methodName) throws Exception
- {
- Method m=clz.getMethod(methodName, null); //获得指定类的指定方法
- Annotation[] aArray=m.getAnnotations(); //获得方法所有的annotation
- for(Annotation one:aArray)
- {
- if(one instanceof CxyAuthority)
- {
- CxyBo tempBo=(CxyBo) ((CxyAuthority)one).boName().newInstance();
- if("c".equals(((CxyAuthority)one).authority()))
- {
- System.out.println("装配信息:普通权限bo装配成功");
- //这里还可以做一些权限控制的操作
- }else if("a".equals(((CxyAuthority)one).authority()))
- {
- System.out.println("装配信息:高级权限bo装配成功");
- //这里还可以做一些权限控制的操作
- }
- tempBo.doSomething();
- }
- }
- }
- }
package com.cxy.annotation; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; /** * @author cxy */ public class AnnotationDetailTest1 { public static void main(String[] args) throws Exception { CxyAction.commonAuthoritymethod(); CxyAction.advanceAuthoritymethod(); System.out.println("============================="); //以下面的两种方式执行这两个方法 CxyAuthorityAp.Processor(CxyAction.class, "commonAuthoritymethod"); System.out.println("------------------------------"); CxyAuthorityAp.Processor(CxyAction.class, "advanceAuthoritymethod"); } } /** 测试目标类,提供了两个不同权限的方法 */ class CxyAction { public static CxyBo bo=new CxyCommonBo(); //初始时候装配的是普通权限的bo //普通权限就能访问的方法 @CxyAuthority(authority="c",boName=CxyCommonBo.class) public static void commonAuthoritymethod() { bo.doSomething(); } //高级权限能访问的方法 @CxyAuthority(authority="a",boName=CxyAdvancedBo.class) public static void advanceAuthoritymethod() { bo.doSomething(); } } /** 一个接口为了演示动态装配而生 */ interface CxyBo { public void doSomething(); } /** 普通权限的bo */ class CxyCommonBo implements CxyBo { //普通业务逻辑 @Override public void doSomething() { System.out.println("执行:普通权限处理方法"); } } /** 高级权限的bo */ class CxyAdvancedBo implements CxyBo { //高级业务逻辑 @Override public void doSomething() { System.out.println("执行:高级权限处理方法"); } } //权限annotation,根据这个标记的authority值来判断装配哪个业务逻辑类 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface CxyAuthority { String authority(); //代表权限 Class boName(); //代表这个权限用什么bo去处理 } /**这个类是@CxyAuthority的annotation处理器 */ class CxyAuthorityAp { //处理器 处理@CxyAuthority标记 public static void Processor(Class clz,String methodName) throws Exception { Method m=clz.getMethod(methodName, null); //获得指定类的指定方法 Annotation[] aArray=m.getAnnotations(); //获得方法所有的annotation for(Annotation one:aArray) { if(one instanceof CxyAuthority) { CxyBo tempBo=(CxyBo) ((CxyAuthority)one).boName().newInstance(); if("c".equals(((CxyAuthority)one).authority())) { System.out.println("装配信息:普通权限bo装配成功"); //这里还可以做一些权限控制的操作 }else if("a".equals(((CxyAuthority)one).authority())) { System.out.println("装配信息:高级权限bo装配成功"); //这里还可以做一些权限控制的操作 } tempBo.doSomething(); } } } }
结果图:
相关推荐
Annotation是Java语言中的一种元数据,它提供了在代码中附加信息的能力,这些信息可以在编译时或运行时被解析和使用。Annotation的本质是一种特殊类型的注解,它允许开发者向编译器、JVM或者工具提供关于代码的额外...
以下是关于 Java Annotation 的详细介绍: 一、为什么使用 Annotation 1. **减少模板代码**:在开发过程中,有时我们需要重复编写相同的模板代码,例如创建 JAX-RPC Web 服务时。通过 Annotation,我们可以让工具...
注解(Annotation)是Java语言中的一个重要特性,自JDK5开始引入,它提供了一种安全的方式,使得程序员可以向源代码中添加元数据(metadata)。元数据是关于数据的数据,它并不改变程序运行方式,但可以被编译器、...
### Annotation注解的深入解析与应用 #### 一、Annotation概览 ##### 1.1 何为元数据 元数据,在计算机科学中,是指用于描述数据的数据,它提供了关于数据本身的附加信息,有助于理解、解释和管理数据。在编程...
7. **元Annotation**:元Annotation是用于定义其他Annotation的Annotation,例如`@Retention`定义Annotation的生命周期(编译时、类加载时或运行时),`@Target`指定Annotation可以应用到哪些程序元素,`@Documented...
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
为了创建自定义的Annotation,我们需要创建一个遵循`MKAnnotation`协议的类,并提供所需的信息。 ```swift class CustomAnnotation: NSObject, MKAnnotation { var coordinate: CLLocationCoordinate2D var title...
赠送jar包:javax.annotation-api-1.2.jar; 赠送原API文档:javax.annotation-api-1.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-1.2.pom;...
@androidx.annotation.NonNull 缺失的兼容、androidx.annotation兼容包
javax.annotation-3.0.jar javax.annotation-3.0.jar javax.annotation-3.0.jar
赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...
#### 二、Annotation技术介绍 **Annotation** 是Sun Microsystems(现已被Oracle收购)在发布JDK 5.0时新增的重要特性之一。这种特性允许开发者在代码中添加元数据,即用来描述其他代码的数据。Annotation可以应用...
赠送jar包:javax.annotation-api-1.3.2.jar; 赠送原API文档:javax.annotation-api-1.3.2-javadoc.jar; 赠送源代码:javax.annotation-api-1.3.2-sources.jar; 赠送Maven依赖信息文件:javax.annotation-api-...
在IT行业中,注解(Annotation)是Java编程语言的一个重要特性,它允许程序员在代码中嵌入元数据,提供了一种安全的方法来修饰程序元素,如类、方法、变量等。注解不会直接影响代码的执行,但它们可以被编译器或运行...
以上是对Hibernate Annotation的简要介绍,深入理解和熟练应用这些注解,将有助于提升你在Java持久化领域的专业技能。对于更详细的用法和高级特性,建议查阅《Hibernate Annotations参考文档-3.20》这份资料,以获取...
【Annotation技术】是Java语言中的一个重要特性,引入于JDK5,主要目的是为程序元素(如包、类、方法、变量等)添加元数据,即附加信息,这些信息可以被编译器、IDE工具或者运行时系统使用。Annotation不会直接改变...
hibernate 注解 annotation 教程
Java annotation 什么是java annotation?annotation 的7种标注类型。nnotation提供了一条与程序元素关联任何信息或者任何元数据(metadata)的途径。从某些方面看,annotation就像修饰符一样被使用,并应用于包、...