I want to write a java annotation which times the method call. something like this:
@TimeIt
public int someMethod() { ... }
and when this method is invoked, it should output on console how long this method took
I know how to do it in python, this is what I want it to do:
from time import time, sleep
def time_it(func):
def wrapper(*args, **kwargs):
start = time()
func(*args, **kwargs)
stop = time()
print "The function", func.__name__, " took %.3f" % (stop - start)
wrapper.__name__ = func.__name__
return wrapper
@time_it
def print_something(*args, **kwargs):
print "before sleeping"
print args, kwargs
sleep(3) # wait 3 seconds
print "after sleeping"
print_something(1, 2, 3, a="what is this?")
So my questions are?
Where do I find some documentation to write something like this, I tried apt
documentation, had no luck with it.
can someone help with writing something like this?
I am surprised to see that no one pointed out java.lang.reflect.Proxy. Its an old thread, but I think this information would be helpful to someone.
Proxy has an interesting property which gives
You can have this proxy for all objects by making them implement some interface or you can use Comparable.
Look for section Dynamic proxies as decorator.
http://www.ibm.com/developerworks/library/j-jtp08305/
As of 2016, there's a nifty aspect annotation library jcabi-aspects.
From the docs:
Annotate your methods with @Loggable annotation and every time they are called, your SLF4J logging facility will receive a message with the details of execution and the total execution time:
Something like this will appear in the log:
Read more about @Loggable here.
Check out the Coda Hale Metrics library. It provides a @Timed annotation for methods that provides this capability. While you're at it check out Code Hale Dropwizard which has examples for how its been integrated into their service framework.
AFAIK, Tomasz is right in saying that this can't be done using annotations. I think the confusion stems from the fact that Python decorators and Java annotations share the same syntax but are completely different in terms of the behavior they offer!
Annotations are metadata attached to your class/methods/fields. This blog post addresses the point of timing methods using AOP. Though it uses Spring, the basic premise remains the same. If you are good to go with an AOP compiler, it shouldn't be too difficult to translate the code. Another reference (spring specific) here.
EDIT: If your aim is to have a overall method timing for your application without using full blown profilers, you can use hprof for collecting total execution statistics.
Simply put: you can't!
Annotations are not pieces of code that get automatically started together with your code, they are just annotation, pieces of information that can be used by other programs working on your code like loading or running it.
What you need is AOP: aspect oriented programming.
As already stated you can't and AOP or hprof should cover most of your needs, but if you insist there's a workaround using JSR269. FYI, apt is obsolete and an annotation processing API and tool has been incorporated into 1.6 (and it is called with the evocative name JSR269).
The workaround would be to create an annotation processor that generates a class that extends the class that contains the method with the
@TimeIt
annotation. This generated class must override the timed method, it will look like the Pythontime_it
but the linefunc(*args, **kwargs)
would be replaced bysuper.methodName(arg1, arg2, ...)
.There are however two caveats: