【问题标题】:Enable Aspect proxy based on runtime condition, Spring AOP?基于运行时条件启用Aspect代理,Spring AOP?
【发布时间】:2014-11-02 08:01:25
【问题描述】:

我正在使用 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 级别

或任何关于如何使日志干净的建议将不胜感激。

谢谢!

【问题讨论】:

    标签: java spring log4j aspectj spring-aop


    【解决方案1】:

    您可以通过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。如here 所述,它可以通过 LTW(加载时编织)轻松应用于 Spring 应用程序。

    【讨论】:

    • 谢谢!我会尝试 !不过我还有一件事要问,logger有什么需要注意的吗?例如:它必须是非静态的,还是必须从哪里创建(注入、构造函数或其他)?
    • 我在tomcat中运行应用程序时遇到一些错误,嵌套异常是org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException: Pointcut expression 'execution(* wodinow.weixin.jaskey..*.* (..)) && if()' 包含不受支持的切入点原语 'if'
    • 如果您愿意,记录器可以是静态的。此问题与 AOP 问题无关。
    • 那么你的意思是没有其他方法可以使用spring aop根据运行时条件进行切点吗?
    • 正确。如果我知道的话,我会告诉你的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多