利用Spring Aop监测每个Controller或方法的执行时长

      • 一、创建自定义注解
      • 二、创建切面
      • 注:Java自定义注解
        • 一、创建自定义注解
        • 二、创建测试类,使用自定义注解
        • 三、解析注解

一、创建自定义注解

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),它们是负责注解其他注解的。

  1. Target:指明注解支持的使用范围,取值可以参考枚举ElementType,以下:
    • ElementType.TYPE //类、接口、枚举
    • ElementType.FIELD //属性
    • ElementType.METHOD //方法
    • ElementType.PARAMETER //参数
    • ElementType.CONSTRUCTOR //构造器
    • ElementType.LOCAL_VARIABLE //局部变量
    • ElementType.ANNOTATION_TYPE //注解
    • ElementType.PACKAGE //包
  2. Retention:指明注解保留的的时间长短,取值参考枚举RetentionPolicy,一下:
    • SOURCE //源文件中保留
    • CLASS //class编译时保留
    • RUNTIME //运行时保留
  3. Inherited:指明该注解类型被自动继承。如果一个annotation注解被@Inherited修饰,那么该注解作用于的类 的子类也会使用该annotation注解。
  4. 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的自定义注解有简单的了解。

你可能感兴趣的:(Spring,java)