package rewards.internal.aspects; import org.apache.log4j.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import rewards.internal.account.AccountRepository; import rewards.internal.monitor.Monitor; import rewards.internal.monitor.MonitorFactory; import rewards.internal.restaurant.RestaurantRepository; import rewards.internal.reward.RewardRepository; /** * An aspect that monitors the performance of all three repositories used in the application. * @see AccountRepository * @see RestaurantRepository * @see RewardRepository */ @Aspect public class RepositoryPerformanceMonitor { private static final Logger logger = Logger.getLogger(RepositoryPerformanceMonitor.class); private MonitorFactory monitorFactory; public RepositoryPerformanceMonitor(MonitorFactory monitorFactory) { this.monitorFactory = monitorFactory; } /** * Times repository method invocations and outputs performance results to a Log4J logger. * @param repositoryMethod The join point representing the intercepted repository method * @return The object returned by the target method * @throws Throwable if thrown by the target method */ @Around("anyRepositoryMethod()") public Object monitor(ProceedingJoinPoint repositoryMethod) throws Throwable { String name = createJoinPointTraceName(repositoryMethod); Monitor monitor = monitorFactory.start(name); try { return repositoryMethod.proceed(); } finally { monitor.stop(); logger.info(monitor); } } @Pointcut("execution(public * rewards.internal.*.*Repository+.*(..))") public void anyRepositoryMethod() { } private String createJoinPointTraceName(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); StringBuilder sb = new StringBuilder(); sb.append(signature.getDeclaringType().getSimpleName()); sb.append('.').append(signature.getName()); return sb.toString(); } }