根据运行时条件启用Aspect代理,Spring AOP?

时间:2014-11-02 08:01:25

标签: java spring log4j aspectj spring-aop

我正在使用Spring AOP来减少现有应用程序的调试日志。

我尝试做的是根据日志级别记录每个方法调用。

我知道Spring会为我的每个类构建一个代理,如果我使用下面的方面,如果它不在调试级别会引入一些开销:

package com.basepackage.aop;

import....

@Aspect
@Component
public class LogAspect {

    private Logger logger=Logger.getLogger(LogAspect.class.getName());

    @Pointcut("execution(* com.basepackage..*.*(..))")//all the method in my app
    private void debug_log(){};

    @Around("debug_log()")//here, I hope I can introduce something like && logger.isDebugeEnable()
    public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable{
        String signature=joinPoint.getSignature().toString();
        String paramList = null;
        Object[] args=joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            paramList+=args[i]+" ";
        }

        String debugMsg="----------enter "+signature;
        if(paramList!=null){
            debugMsg+="\nparam: "+paramList;
        }

        LogUtil.debug(debugMsg);//will delegate to log4j
        try{
            Object returnObject= joinPoint.proceed();
            LogUtil.debug("--------return form"+signature);//will delegate to log4j
            return returnObject;
        }
        catch(Throwable t){
            LogUtil.error("--------error from "+signature, t);//will delegate to log4j
            throw t;
        }
    }
}

我希望只有当log4j level&lt; = debug level时,Spring AOP才会为每个类构建一个代理。

或者关于如何使日志清洁的任何更多建议将受到高度赞赏。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以通过if()向您的切入点添加激活条件,请参阅 AspectJ documentation。然后切入点返回boolean而不是void,并包含一个动态评估条件并返回结果的正文:

@Pointcut("execution(* com.basepackage..*.*(..)) && if()")
public boolean debug_log() {
    return logger.isdebugEnabled();
};

因为它是动态的,我想代理仍在创建,但是建议正文不会被执行。为了摆脱代理,从Spring AOP切换到不使用代理的AspectJ,效率更高。 AspectJ可以通过LTW(加载时编织)轻松集成到Apring应用程序中。

<强>更新

Spring AOP只是一种基于代理的“AOP lite”方法拦截方法,而不是像AspectJ这样的完整框架。因此,它不支持if()切入点原语,请参阅here。话虽如此,我建议你切换到完整的AspectJ。它可以通过LTW(加载时编织)轻松应用于Spring应用程序,如here所述。