3

我有一个类似于以下的 Java 类:

public class Foo{
   public void doSomething(){
     StageA a = new StageA();
     StageB b = new StageB();
     StageC c = new StageC();
     a.execute();
     b.execute();
     c.execute();
   }
}

现在,假设我不能真正编辑这个类本身,我还可以使用spring AOParound来应用记录execute方法吗?(大概不使用aspect4j

4

3 回答 3

2

已编辑: 我认为在您的情况下,如果不更改 Foo 或 Stage 类,就不可能记录每个“执行”方法的执行。因为 Stage... 类不是由容器管理的。您只能记录 doSomething 方法何时开始执行(如果 Foo 类由 Spring 容器管理),您无法控制它的执行流程。

如果您的类将由 Spring 容器管理,那么您可以轻松做到这一点。您应该简单地为 Stage... 类而不是 Foo 类编写 Spring AOP“围绕”方面。

这是一个简单的日志记录方面的示例:

@Component
@Aspect
@Order(value=2)
public class LoggingAspect {

    @Around("execution(* com.blablabla.server..*.*(..))")
    public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable{
        final Logger logger = LoggerFactory.getLogger(joinPoint.getTarget().getClass().getName());
        Object retVal = null;

        try {
            StringBuffer startMessageStringBuffer = new StringBuffer();

            startMessageStringBuffer.append("Start method ");
            startMessageStringBuffer.append(joinPoint.getSignature().getName());
            startMessageStringBuffer.append("(");

            Object[] args = joinPoint.getArgs();
            for (int i = 0; i < args.length; i++) {
                startMessageStringBuffer.append(args[i]).append(",");
            }
            if (args.length > 0) {
                startMessageStringBuffer.deleteCharAt(startMessageStringBuffer.length() - 1);
            }

            startMessageStringBuffer.append(")");

            logger.trace(startMessageStringBuffer.toString());

            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            retVal = joinPoint.proceed();

            stopWatch.stop();

            StringBuffer endMessageStringBuffer = new StringBuffer();
            endMessageStringBuffer.append("Finish method ");
            endMessageStringBuffer.append(joinPoint.getSignature().getName());
            endMessageStringBuffer.append("(..); execution time: ");
            endMessageStringBuffer.append(stopWatch.getTotalTimeMillis());
            endMessageStringBuffer.append(" ms;");

            logger.trace(endMessageStringBuffer.toString());
        } catch (Throwable ex) {
            StringBuffer errorMessageStringBuffer = new StringBuffer();

             // Create error message 
             logger.error(errorMessageStringBuffer.toString(), e)

            throw ex;
        }

        return retVal;
    }
}
于 2012-10-18T09:37:08.683 回答
2

好吧,您可以记录方法并且它需要时间(用于性能),但我认为您无法记录方法正在做什么。

来自Spring 文档

围绕建议:围绕连接点的建议,例如方法调用。这是最有力的建议。环绕通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续到连接点还是通过返回自己的返回值或抛出异常来缩短建议的方法执行。


如果您在方法内部使用 log4j 记录器,则可以通过配置 log4j 记录方法正在执行的操作。

(大概没有使用aspect4j)

--> Spring 内部使用aspectJ

检查here以获取参考和示例

于 2012-10-18T09:30:29.737 回答
1

是的,您可以使用名称如下的切入点定位方法编写@Around建议:executionexecute()

@Around("execution(* execute(..))")
public Object execute(ProceedingJoinPoint pjp) throws Throwable
{
    // Log statements before the call;

    Object obj = pjp.proceed();

    // Log statements after the call;

    return obj;
}
于 2012-10-18T09:40:45.863 回答