I've done this using Spring AOP.
Sometime I need an information about how much time does it take to execute some methods in my project (Controller's method in example).
In servlet xml I put
<aop:aspectj-autoproxy/>
Also, I need to create the class for aspects:
@Component
@Aspect
public class SystemArchitecture {
    @Pointcut("execution(* org.mywebapp.controller..*.*(..))")
    public void businessController() {
    }
}
And profiler aspect:
@Component
@Aspect
public class TimeExecutionProfiler {
    private static final Logger logger = LoggerFactory.getLogger(TimeExecutionProfiler.class);
    @Around("org.mywebapp.util.aspects.SystemArchitecture.businessController()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        logger.info("ServicesProfiler.profile(): Going to call the method: {}", pjp.getSignature().getName());
        Object output = pjp.proceed();
        logger.info("ServicesProfiler.profile(): Method execution completed.");
        long elapsedTime = System.currentTimeMillis() - start;
        logger.info("ServicesProfiler.profile(): Method execution time: " + elapsedTime + " milliseconds.");
        return output;
    }
    @After("org.mywebapp.util.aspects.SystemArchitecture.businessController()")
    public void profileMemory() {
        logger.info("JVM memory in use = {}", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
    }
}
That's all.
When I request a page from my webapp, the information about method executing time and JVM memory usage prints out in my webapp's log file.