Java 基于运行时条件启用方面代理,Spring AOP?
我正在使用SpringAOP来减少现有应用程序的调试日志 我试图做的是根据日志级别记录每个方法调用 我知道,如果我使用以下方面,Spring将为我的每个类构造一个代理,如果它不在调试级别,这将引入一些开销:Java 基于运行时条件启用方面代理,Spring AOP?,java,spring,log4j,aspectj,spring-aop,Java,Spring,Log4j,Aspectj,Spring Aop,我正在使用SpringAOP来减少现有应用程序的调试日志 我试图做的是根据日志级别记录每个方法调用 我知道,如果我使用以下方面,Spring将为我的每个类构造一个代理,如果它不在调试级别,这将引入一些开销: package com.basepackage.aop; import.... @Aspect @Component public class LogAspect { private Logger logger=Logger.getLogger(LogAspect.class.
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;
}
}
}
package com.basepackage.aop;
进口
@面貌
@组成部分
公共类日志方面{
私有Logger=Logger.getLogger(LogAspect.class.getName());
@切入点(“execution(*com.basepackage..**(..))//我的应用程序中的所有方法
私有void debug_log(){};
@关于(“debug_log()”/,在这里,我希望能介绍类似于&&logger.isDebugeEnable()的内容
围绕日志的公共对象(ProceedingJoinPoint joinPoint)抛出可丢弃的{
字符串签名=joinPoint.getSignature().toString();
字符串paramList=null;
对象[]args=joinPoint.getArgs();
对于(int i=0;i
我希望只有当log4j级别时,才能通过
if()
向切入点添加激活条件,请参阅。切入点然后返回boolean
而不是void
,并包含一个动态评估条件并返回结果的主体:
@Pointcut(“执行(*com.basepackage..**(..))&&if())
公共布尔调试日志(){
返回logger.isdebugEnabled();
};
因为它是动态的,所以我猜代理仍在创建中,但不会执行通知体。为了摆脱代理,从SpringAOP切换到AspectJ,它不使用代理,而且效率更高。AspectJ可以通过LTW(加载时编织)轻松集成到Apring应用程序中
更新:
SpringAOP只是一种用于方法拦截的基于代理的“AOP-lite”方法,而不是像AspectJ那样成熟的框架。因此,它不支持
if()
pointcut原语,请参阅。话虽如此,我建议您切换到完整的AspectJ。如前所述,它可以通过LTW(加载时间编织)轻松应用于Spring应用。谢谢!我会努力的!但是我还有一件事要问,记录器是否有需要注意的地方?例如:它是否必须是非静态的,或者必须从何处创建(注入、构造函数或其他东西)?我在tomcat中运行应用程序时出错,嵌套的异常是org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException:Pointcut表达式“execution(*wodinow.weixin.jaskey..*(..)&&if()'包含不支持的切入点原语'if'如果您愿意,记录器可以是静态的。这个问题与AOP问题无关。所以你的意思是没有其他方法可以使用spring AOP基于运行时cindition生成切点吗?正确。如果我知道的话,我会告诉你的。