Spring AOP:排除避免切入点的最终类和枚举

时间:2014-10-31 14:04:33

标签: spring aop aspectj spring-aop

我正在尝试使用Spring AOP实现Logging。我已经定义了

@Pointcut("execution(* com.mycom..*(..))")
private void framework() {}

@Around("framework()")
public Object aroundAdviceFramework(ProceedingJoinPoint jp) throws Throwable {
    if (logger.isDebugEnabled())
        logger.debug("DEBUG:: {}  {}  Enter", jp.getTarget().getClass().getName(), jp.getSignature().getName());
    Object returnVal = jp.proceed(jp.getArgs());
    if (logger.isDebugEnabled())
        logger.debug("DEBUG:: {}  {}  Out", jp.getTarget().getClass().getName(), jp.getSignature().getName());
    logger.info("INFO:: " + jp.getTarget().getClass().getName() + " " + jp.getSignature().getName() + " Finished:");
    return returnVal;
}

mycom包及其子包下有很多类。有些课程是enum和final class。 因此我得到了

nested exception is org.springframework.aop.framework.AopConfigException: 
Could not generate CGLIB subclass of class [class com.mycom.util.BancsServiceProvider]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.mycom.util.BancsServiceProvider
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)

有没有办法使用某种正则表达式排除所有最终类和枚举类的日志记录。 注意:我在不同的包中都有枚举类。使用完整的类名排除它们很困难。


更新2014-11-17(尝试kriegaex的解决方案):

我尝试使用

@Pointcut("!within(is(FinalType))")

但我收到了以下错误

Pointcut is not well-formed: expecting ')' at character position 10

!内(是(FinalType))

我在pom文件中添加了这个maven依赖项

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.4</version>
    </dependency>

我还添加了这个maven依赖

   <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.4</version>
    </dependency>

现在,一切都像魅力一样。有什么想法,这里发生了什么?

1 个答案:

答案 0 :(得分:11)

目前,您可以通过AspectJ 1.6.9中引入的is()切入点语法排除枚举,方面,接口,内部类型,匿名类型,另请参阅我的回答here

目前你不能做的是通过AspectJ语法排除最终类型。但我认为这是有道理的,所以我为它创建了一个ticket

如何排除枚举:

@Pointcut("execution(* com.mycom..*(..)) && !within(is(EnumType))")

更新: AspectJ 1.8.4已发布,另请参阅官方download section中的概述。在Maven Central上,还没有下载,但我想很快就会发布。如果可用,this link将有效,目前它会产生404错误。

那么为什么这个版本很有趣?由于上面提到的故障单已经解决,并且截至目前已有新的切入点原语is(FinalType),请参阅1.8.4 release notes

所以现在您要求的完整解决方案如下所示:

@Pointcut(
    "execution(* com.mycom..*(..)) && " +
    "!within(is(EnumType)) && " +
    "!within(is(FinalType))"
)

我确认它的效果是这样的。