在 java 中编写自定义注释 - TimeCounter 注释示例
Writing custom annotations in java - TimeCounter annotation example
基本上我需要跟踪在使用自定义注释的方法中花费的时间。 (我知道 spring AOP 可以用于此,但我们不能在我们的产品中使用它)。
public class TimeCounterDemo {
@TimeCounter
public void trackMyTimeSpentUsingAnnotation()
{
//some heavy processing stuff
}
}
public @interface TimeCounter {
//need help with this implementation.
}
所以,我的要求是完成TimeCounter
注解。
要求很简单-
- 记录方法启动时间。
- 记录方法结束时间。
- 记录在方法中花费的总时间。
- 执行的方法名称
有人可以帮助解决如何根据上述要求实现此注释。
提前致谢。
您无需编写注释,而是直接在您的方法中实现时间跟踪。
方法中的前两行必须是
long startTime = System.currentTimeMillis();
logger.info("Method started at = " + new Date(startTime);
现在您必须记录该方法所用的总时间。这可以通过将以下语句写入相同的方法来完成
logger.info("Total time taken by the method is = " + (System.currentTimeMillis() - startTime));
已经有很多库提供了这样的注释。
如果您想要自己的实现,其中一种方法是使用 dynamic proxies:
您的 TimeCounterDemo
可能是这样的:
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(界面)
public interface ITimerCounterDemo {
@TimeCounter
public void trackMyTimeSpentUsingAnnotation();
public void someOtherMethod(int a);
}
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);
}
}
正在测试计时器:
public class TimerTest {
public static void main(String[] args) throws InterruptedException {
ITimerCounterDemo t = (ITimerCounterDemo) TimerProxy.newInstance(new TimerCounterDemo());
t.someOtherMethod(10);
t.trackMyTimeSpentUsingAnnotation();
}
}
输出:
In someothermethod with value:: 10
TimerCounterDemo:: Going to sleep
TimerCounterDemo:: Completed.
trackMyTimeSpentUsingAnnotation executed in 2 seconds
您可以阅读更多相关信息here and
基本上我需要跟踪在使用自定义注释的方法中花费的时间。 (我知道 spring AOP 可以用于此,但我们不能在我们的产品中使用它)。
public class TimeCounterDemo {
@TimeCounter
public void trackMyTimeSpentUsingAnnotation()
{
//some heavy processing stuff
}
}
public @interface TimeCounter {
//need help with this implementation.
}
所以,我的要求是完成TimeCounter
注解。
要求很简单-
- 记录方法启动时间。
- 记录方法结束时间。
- 记录在方法中花费的总时间。
- 执行的方法名称
有人可以帮助解决如何根据上述要求实现此注释。
提前致谢。
您无需编写注释,而是直接在您的方法中实现时间跟踪。 方法中的前两行必须是
long startTime = System.currentTimeMillis();
logger.info("Method started at = " + new Date(startTime);
现在您必须记录该方法所用的总时间。这可以通过将以下语句写入相同的方法来完成
logger.info("Total time taken by the method is = " + (System.currentTimeMillis() - startTime));
已经有很多库提供了这样的注释。 如果您想要自己的实现,其中一种方法是使用 dynamic proxies:
您的 TimeCounterDemo
可能是这样的:
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(界面)
public interface ITimerCounterDemo {
@TimeCounter
public void trackMyTimeSpentUsingAnnotation();
public void someOtherMethod(int a);
}
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);
}
}
正在测试计时器:
public class TimerTest {
public static void main(String[] args) throws InterruptedException {
ITimerCounterDemo t = (ITimerCounterDemo) TimerProxy.newInstance(new TimerCounterDemo());
t.someOtherMethod(10);
t.trackMyTimeSpentUsingAnnotation();
}
}
输出:
In someothermethod with value:: 10
TimerCounterDemo:: Going to sleep
TimerCounterDemo:: Completed.
trackMyTimeSpentUsingAnnotation executed in 2 seconds
您可以阅读更多相关信息here and