class CircuitBreakerAspect {

    @Around("@annotation(circuitBreakerAnnotation)")
    public Object monitor(final ProceedingJoinPoint pjp,
              CircuitBreaker circuitBreakerAnnotation) throws Throwable {
        final String name = circuitBreakerAnnotation.name();

        org.fishwife.jrugged.CircuitBreaker circuitBreaker =
                circuitBreakerFactory.findCircuitBreaker(name);

        if (circuitBreaker == null) {
            DefaultFailureInterpreter dfi =
                    new DefaultFailureInterpreter(
                            circuitBreakerAnnotation.ignore(),
                            circuitBreakerAnnotation.limit(),
                            circuitBreakerAnnotation.windowMillis());

            CircuitBreakerConfig config = new CircuitBreakerConfig(
                    circuitBreakerAnnotation.resetMillis(), dfi);

            circuitBreaker =
                    circuitBreakerFactory.createCircuitBreaker(name, config);
        }

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

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

    public  CircuitBreakerAspect();

}