While this is not an actual practical answer to your question just yet (some good answers have been with respect to AOP), I believe the concept of ARM in Java 7 should be a viable option for implementing something like this on a small scale.
You could define a utility logging class and a factory to produce that class, something like the following:
public class TimerFactory
{
private static final Logger log = ...; // Obtain however
static class Timer implements Disposable<RuntimeException>
{
private final long startTime;
private final String name;
private Timer(String name)
{
this.name = name;
startTime= System.currentTimeMillis();
log.info("begin - " + name);
}
public void close()
{
final long t2 = System.currentTimeMillis();
log.info("end - " + name + ", took " + (t2 - t1) + "ms.");
}
}
public static Timer getTimer(String name)
{
return new Timer(name);
}
}
Now with that boilerplate out of the way (essentially an encapsulation of your logging behaviour), it could be called as follows:
public void m() {
try (TimerFactory.getTimer("m()")) {
/* method body */
}
}
The first log method would be called at the entrance to the try block, and the start time recorded. When the try block was exited, the resource (the Timer
in this case) would automatically be "closed", which would cause the final time to be calculated and logged. Note as well that because this is a try
block, the end logging will happen regardless of whether an exception is thrown or not. Your original code should probably use a try-finally block to ensure that the logging is actually completed.
Obviously this still requires you to put some logging code at each site, so is not really a replacement for clever pointcuts and AOP, even once Java 7 is released. However, if you find yourself dropping the logging in every now and then into perhaps a handful of methods, this pattern is a good way to abstract out the logging concerns and allow you to reuse it with the minimum of boilerplate.