一、创建自定义注解
package com.lishicloud.qc.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface TimeOperation {
//自定义的一个参数,可以在注解后面指定参数,如@TimeOperation(name = "test")
String name() default "sam";
String type();
}
二、创建切面
package com.lishicloud.qc.plugin.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeAspect {
//开始时间
private Long begin;
//结束时间
private Long end;
/**
* 此注解规定了切入点
* "@annotation(com.lishicloud.qc.common.annotation.TimeOperation)" 表示标有@TimeOperation注解的方法
* "execution(public * com.lishicloud.qc.web.*.*(..))" 表示com.lishicloud.qc.web下的所有类中的所有方法
*/
@Pointcut("@annotation(com.lishicloud.qc.common.annotation.TimeOperation)")
public void logOperation(){}
@Before(value = "logOperation()")
public void before(){
begin = System.currentTimeMillis();
}
@After(value = "logOperation()")
public void after(){
end = System.currentTimeMillis();
System.out.println("用时"+(end - begin)+"毫秒");
}
}
注:Java自定义注解
Java在1.5开始引入了注解,目前流行的框架都在用注解,可想而知注解的强大之处。
以下通过自定义注解来深入了解java注解。
一、创建自定义注解
package com.sam.annotation;
import java.lang.annotation.*;
/**
* @author sam
* @since 2017/7/13
*/
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyMessage {
String name() default "sam";
int num() default 0;
String desc();
}
@Target、@Retention、@Inherited、@Documented为元注解(meta-annotation),它们是负责注解其他注解的。
- Target:指明注解支持的使用范围,取值可以参考枚举ElementType,以下:
- ElementType.TYPE //类、接口、枚举
- ElementType.FIELD //属性
- ElementType.METHOD //方法
- ElementType.PARAMETER //参数
- ElementType.CONSTRUCTOR //构造器
- ElementType.LOCAL_VARIABLE //局部变量
- ElementType.ANNOTATION_TYPE //注解
- ElementType.PACKAGE //包
- Retention:指明注解保留的的时间长短,取值参考枚举RetentionPolicy,一下:
- SOURCE //源文件中保留
- CLASS //class编译时保留
- RUNTIME //运行时保留
- Inherited:指明该注解类型被自动继承。如果一个annotation注解被@Inherited修饰,那么该注解作用于的类 的子类也会使用该annotation注解。
- Documented:指明拥有这个注解的元素可以被javadoc此类的工具文档化。
二、创建测试类,使用自定义注解
package com.sam.annotation;
/**
* @author sam
* @since 2017/7/13
*/
public class AnnotationTest {
@MyMessage(num = 10, desc = "参数a")
private static int a;
@MyMessage(name = "Sam test", desc = "测试方法test")
public void test() {
System.out.println("test");
}
}
在该类中的属性和方法,使用了自定义的注解,并指明了参数。
那么现在就需要解析自定义的注解。
三、解析注解
使用反射机制处理自定义注解
package com.sam.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 使用反射处理注解
*
* @author sam
* @since 2017/7/13
*/
public class MyMessageProcessor {
public static void main(String[] args) {
try {
//加载annotationTest.class类
Class clazz = MyMessageProcessor.class.getClassLoader().loadClass("com.sam.annotation.AnnotationTest");
//获取属性
Field[] fields = clazz.getDeclaredFields();
//遍历属性
for (Field field : fields) {
MyMessage myMessage = field.getAnnotation(MyMessage.class);
System.out.println("name:" + myMessage.name() + " num:" + myMessage.num() + " desc:" + myMessage.desc());
}
//获取类中的方法
Method[] methods = clazz.getMethods();
//遍历方法
for (Method method : methods) {
//判断方法是否带有MyMessage注解
if (method.isAnnotationPresent(MyMessage.class)) {
// 获取所有注解 method.getDeclaredAnnotations();
// 获取MyMessage注解
MyMessage myMessage = method.getAnnotation(MyMessage.class);
System.out.println("name:" + myMessage.name() + " num:" + myMessage.num() + " desc:" + myMessage.desc());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行MyMessageProcessor 得到结果:
name:sam num:10 desc:参数a
name:Sam test num:0 desc:测试方法test
Process finished with exit code 0
具体定制注解所实现的内容,可以在MyMessageProcessor.java中进行修改。
自此,已经对java的自定义注解有简单的了解。