在java中编写自定义注释-计时器注释示例

在java中编写自定义注释-计时器注释示例,java,java-8,annotations,java-annotations,Java,Java 8,Annotations,Java Annotations,基本上,我需要跟踪在使用自定义注释的方法中花费的时间。(我知道spring AOP可以用于此,但我们不能在我们的产品中使用它) 因此,我的要求是完成计时器注释。 要求很简单- 方法启动的日志时间 方法结束的日志时间 记录在方法中花费的总时间 已执行方法的名称 有人能帮助我们实现上述需求的注释吗 提前感谢。您不用编写注释,而是直接在方法中实现时间跟踪。 方法中的前两行必须为 long startTime = System.currentTimeMillis(); logger.info("

基本上,我需要跟踪在使用自定义注释的方法中花费的时间。(我知道spring AOP可以用于此,但我们不能在我们的产品中使用它)

因此,我的要求是完成
计时器
注释。 要求很简单-

  • 方法启动的日志时间
  • 方法结束的日志时间
  • 记录在方法中花费的总时间
  • 已执行方法的名称
  • 有人能帮助我们实现上述需求的注释吗


    提前感谢。

    您不用编写注释,而是直接在方法中实现时间跟踪。 方法中的前两行必须为

    long startTime = System.currentTimeMillis();
    logger.info("Method started at = " + new Date(startTime);
    
    现在您必须记录该方法花费的总时间。这可以通过将下面的语句写入相同的方法来实现

    logger.info("Total time taken by the method is = " + (System.currentTimeMillis() - startTime));
    

    已经有很多库提供了这样的注释。 如果您想要自己的实现,其中一种方法是使用:

    以下是您的
    TimeCounterDemo
    的外观:

    计时器(注释)

    import java.lang.annotation.ElementType;
    导入java.lang.annotation.Retention;
    导入java.lang.annotation.RetentionPolicy;
    导入java.lang.annotation.Target;
    @保留(RetentionPolicy.RUNTIME)
    @目标(ElementType.METHOD)
    公共@接口计时器{
    }
    
    ITimerCounterDemo(接口)

    公共接口ITimerCounterDemo{
    @计时器
    public void trackMyTimeSpentUsingAnnotation();
    公共无效其他方法(INTA);
    }
    
    TimerCounterDemo(上述接口的实现)

    
    公共类TimerCounterDemo实现了ITimerCounterDemo{
    public void trackMyTimeSpentUsingAnnotation(){
    System.out.println(“TimerCounterDemo::入睡”);
    试一试{
    《睡眠》(2000年);
    }捕捉(中断异常e){
    }
    System.out.println(“TimerCounterDemo::Completed.”);
    }
    公共void someOtherMethod(int a){
    System.out.println(“In someothermethod with value::”+a);
    }
    }
    
    TimerProxy

    import java.lang.reflect.InvocationHandler;
    导入java.lang.reflect.Method;
    导入java.lang.reflect.Proxy;
    导入java.time.Duration;
    导入java.time.LocalDateTime;
    导入java.util.Objects;
    公共类TimerProxy实现调用处理程序{
    私有对象targetObj;
    公共静态对象newInstance(对象targetObj){
    Objects.requirennull(targetObj);
    返回Proxy.newProxyInstance(
    targetObj.getClass().getClassLoader(),
    targetObj.getClass().getInterfaces(),
    新TimerProxy(目标北京)
    );
    }
    专用时间Proxy(对象targetObj){
    this.targetObj=targetObj;
    }
    @凌驾
    公共对象调用(对象代理、方法、对象[]args)抛出Throwable{
    if(方法isAnnotationPresent(TimeCounter.class)){
    LocalDateTime start=LocalDateTime.now();
    objectreturnobj=method.invoke(targetObj,args);
    System.out.println(方法.getName()+“在中执行”
    +Duration.between(start,LocalDateTime.now()).getSeconds()+“seconds”);
    返回OBJ;
    }
    invoke(targetObj,args);
    }
    }
    
    测试计时器:

    公共类时间测试{
    公共静态void main(字符串[]args)引发InterruptedException{
    ITimerCounterDemo t=(ITimerCounterDemo)TimerProxy.newInstance(new TimerCounterDemo());
    t、 其他方法(10);
    t、 TrackMyTimePentusingAnnotation();
    }
    }
    
    输出:

    值为::10的someothermethod中的
    
    TimerCounterDemo::要睡觉了吗
    TimerCounterDemo::已完成。
    trackMyTimeSpentUsingAnnotation在2秒内执行
    

    你可以多读一些,我知道这一点。。你能删除你的答案吗。我正在考虑删除这个QQ+1。因此,您的实现使用您链接的动态代理。对吗?和是由实现类继承的接口方法上的注释。这篇帖子说otherway-@joven,没错,我们正在使用代理。我们没有将
    @TimerCounter
    放在子类继承的接口上;这样我们就可以在
    invoke
    方法中检查注释。代理与接口一起工作(因此称为动态代理)。为了简单起见,我将它放在接口上。您也可以将注释放在类内声明的方法上。您有
    targetObj
    ,可以在其方法中检查注释(如:
    targetObj.getClass().getMethods()
    ),并相应地采取行动。@joven注意,我们仍然(当我们将
    @TimeCounter
    放在
    TimerCounterDemo
    中的方法定义上时)需要
    ITimerCounterDemo
    。这是因为代理与接口一起工作。我们不能有
    TimerCounterDemo t=(TimerCounterDemo)TimerProxy.newInstance(new TimerCounterDemo())。强制转换和分配类型必须是由
    TimerCounterDemo
    实现的接口之一。
    logger.info("Total time taken by the method is = " + (System.currentTimeMillis() - startTime));