【问题标题】:Spring AOP: exclude avoid final classes and enums from pointcutSpring AOP:从切入点排除避免最终类和枚举
【发布时间】:2014-10-31 14:04:33
【问题描述】:

我正在尝试使用 Spring AOP 实现日志记录。我已经定义了

@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 包及其子包下有很多类。一些类是枚举和最终类。 正因为如此,我得到了

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

!within(is(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>

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

【问题讨论】:

    标签: spring aop aspectj spring-aop


    【解决方案1】:

    目前,您可以通过 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))"
    )
    

    我确认它是这样工作的。

    【讨论】:

    • 票证已解决,AspectJ 1.8.4 已发布,请参阅更新后的答案。
    • 我现在尝试了,但出现错误 Pointcut is not well-formed: Expecting ')' at character position 10 !within(is(FinalType))
    • 那你没有使用1.8.4版本编译。
    • 现在 !within(is(FinalType)) 工作正常。请阅读编辑后的问题。
    • 我不明白你还想知道什么。您正在使用 AspectJ 1.8.4 中的全新功能,但在您的构建和运行时依赖项中没有该版本。这真的需要解释吗?现在它正在工作,很高兴。 P.S.:如果您不以某种方式编辑您的问题,以显示什么是原始问题以及哪一部分是更新,则很难识别。
    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多