class PerformanceMonitorAspect {

    @Around("@annotation(performanceMonitorAnnotation)")
    public Object monitor(final ProceedingJoinPoint pjp,
            PerformanceMonitor performanceMonitorAnnotation) throws Throwable {
        String monitorName = performanceMonitorAnnotation.value();

        if (logger.isDebugEnabled()) {
            logger.debug("Have @PerformanceMonitor method with monitor name {}, " +
                    "wrapping call on method {} of target object {}",
                    new Object[]{
                            monitorName,
                            pjp.getSignature().getName(),
                            pjp.getTarget()});
        }

        org.fishwife.jrugged.PerformanceMonitor performanceMonitor =
                performanceMonitorFactory.findPerformanceMonitor(
                            monitorName);

        if (performanceMonitor == null) {
            performanceMonitor =
                    performanceMonitorFactory.createPerformanceMonitor(
                            monitorName);
        }

        return performanceMonitor.invoke(
                new Callable<Object>() {
                    public Object call() throws Exception {
                        Object retval;
                        try {
                            retval = pjp.proceed();
                        } catch (Throwable e) {
                            if (e instanceof Exception) {
                                throw (Exception) e;
                            } else {
                                throw (Error) e;
                            }
                        }
                        return retval;
                    }
                }
        );
    }

    public  PerformanceMonitorAspect();

}