简体   繁体   English

在 java 中编写自定义注释 - TimeCounter 注释示例

[英]Writing custom annotations in java - TimeCounter annotation example

Basically I have a requirement to track time spent in a method using custom annotation.基本上,我需要跟踪使用自定义注释的方法所花费的时间。 (I know spring AOP can be used for this, but we can not use it in our product). (我知道 spring AOP 可以用于此,但我们不能在我们的产品中使用它)。

public class TimeCounterDemo {
    
    @TimeCounter
    public void trackMyTimeSpentUsingAnnotation()
    {
        //some heavy processing stuff
    }   
}

public @interface TimeCounter {
  //need help with this implementation.
}

So, my requirement is to complete the TimeCounter annotation.所以,我的要求是完成TimeCounter注释。 The requirement are simple -要求很简单——

  1. Log time of method start.方法开始的记录时间。
  2. Log time of method end.方法结束的记录时间。
  3. Log total time spent in method.记录在方法中花费的总时间。
  4. Name of method executed执行的方法名称

Could someone help on how to implement this annotation to above requirements.有人可以帮助解决如何根据上述要求实现此注释。

Thanks in advance.提前致谢。

There are already many libraries that have such annotations available.已经有很多库提供了这样的注释。 If you want your own implementation, one of the appraoches would be to use dynamic proxies :如果您想要自己的实现,其中一种方法是使用动态代理

Here's how your TimeCounterDemo may look like:下面是您的TimeCounterDemo的样子:

TimeCounter (Annotation) TimeCounter(注解)

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 TimeCounter {

}

ITimerCounterDemo (Interface) ITimerCounterDemo(接口)

public interface ITimerCounterDemo {
    @TimeCounter
    public void trackMyTimeSpentUsingAnnotation();

    public void someOtherMethod(int a);
}

TimerCounterDemo (Implementation of above interface) TimerCounterDemo(上述接口的实现)


public class TimerCounterDemo implements ITimerCounterDemo {
    
    public void trackMyTimeSpentUsingAnnotation() {
        System.out.println("TimerCounterDemo:: Going to sleep");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("TimerCounterDemo:: Completed.");
    }

    public void someOtherMethod(int a) {
        System.out.println("In someothermethod with value:: " + a);
    }
}

TimerProxy定时器代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Objects;

public class TimerProxy implements InvocationHandler {

    private Object targetObj;

    public static Object newInstance(Object targetObj) {
        Objects.requireNonNull(targetObj);
        return Proxy.newProxyInstance(
                      targetObj.getClass().getClassLoader(), 
                      targetObj.getClass().getInterfaces(),
                      new TimerProxy(targetObj)
               );
    }

    private TimerProxy(Object targetObj) {
        this.targetObj = targetObj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (method.isAnnotationPresent(TimeCounter.class)) {

            LocalDateTime start = LocalDateTime.now();
            Object returnObj = method.invoke(targetObj, args);

            System.out.println(method.getName() + " executed in "
                    + Duration.between(start, LocalDateTime.now()).getSeconds() + " seconds");
            return returnObj;
        }

        return method.invoke(targetObj, args);
    }

}

Testing the timer:测试计时器:

public class TimerTest {
    public static void main(String[] args) throws InterruptedException {
        ITimerCounterDemo t = (ITimerCounterDemo) TimerProxy.newInstance(new TimerCounterDemo());
        t.someOtherMethod(10);
        t.trackMyTimeSpentUsingAnnotation();
    }
}

Output: Output:

In someothermethod with value:: 10
TimerCounterDemo:: Going to sleep
TimerCounterDemo:: Completed.
trackMyTimeSpentUsingAnnotation executed in 2 seconds

You can read more about it here and here您可以在此处此处阅读有关它的更多信息

Instead of writing an annotation, you implement time tracking directly in your method.您无需编写注释,而是直接在您的方法中实现时间跟踪。 The first 2 lines in your method must be您方法中的前 2 行必须是

long startTime = System.currentTimeMillis();
logger.info("Method started at = " + new Date(startTime);

Now you have to log the total time taken by the method.现在您必须记录该方法所花费的总时间。 This can be done by writing the below statement into the same method这可以通过将以下语句写入相同的方法来完成

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM