View Javadoc

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  }