1 /* Copyright (c) 2008-2009 HomeAway, Inc.
2 * All rights reserved. http://www.perf4j.org
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.perf4j.aop;
17
18 import org.aspectj.lang.ProceedingJoinPoint;
19 import org.aspectj.lang.annotation.Around;
20 import org.aspectj.lang.annotation.Aspect;
21 import org.perf4j.LoggingStopWatch;
22
23 /**
24 * This is the base class for TimingAspects that use the AspectJ framework (a better name for this class work probably
25 * be AspectJTimingAspect, but for backwards compatibility reasons it keeps the AbstractTimingAspect name).
26 * Subclasses just need to implement the {@link #newStopWatch} method to use their logging framework of choice
27 * (e.g. log4j or java.logging) to persist the StopWatch log message.
28 *
29 * @author Alex Devine
30 */
31 @Aspect
32 public abstract class AbstractTimingAspect extends AgnosticTimingAspect {
33 /**
34 * This advice is used to add the StopWatch logging statements around method executions that have been tagged
35 * with the Profiled annotation.
36 *
37 * @param pjp The ProceedingJoinPoint encapulates the method around which this aspect advice runs.
38 * @param profiled The profiled annotation that was attached to the method.
39 * @return The return value from the method that was executed.
40 * @throws Throwable Any exceptions thrown by the underlying method.
41 */
42 @Around(value = "execution(* *(..)) && @annotation(profiled)", argNames = "pjp,profiled")
43 public Object doPerfLogging(final ProceedingJoinPoint pjp, Profiled profiled) throws Throwable {
44 //We just delegate to the super class, wrapping the AspectJ-specific ProceedingJoinPoint as an AbstractJoinPoint
45 return runProfiledMethod(
46 new AbstractJoinPoint() {
47 public Object proceed() throws Throwable { return pjp.proceed(); }
48
49 public Object getExecutingObject() { return pjp.getThis(); }
50
51 public Object[] getParameters() { return pjp.getArgs(); }
52
53 public String getMethodName() { return pjp.getSignature().getName(); }
54 },
55 profiled,
56 newStopWatch(profiled.logger() + "", profiled.level())
57 );
58 }
59
60 /**
61 * Subclasses should implement this method to return a LoggingStopWatch that should be used to time the wrapped
62 * code block.
63 *
64 * @param loggerName The name of the logger to use for persisting StopWatch messages.
65 * @param levelName The level at which the message should be logged.
66 * @return The new LoggingStopWatch.
67 */
68 protected abstract LoggingStopWatch newStopWatch(String loggerName, String levelName);
69 }