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

Viv*_*l21 5 aop spring 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;
}
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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


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

我试过用

@Pointcut("!within(is(FinalType))")
Run Code Online (Sandbox Code Playgroud)

但我得到以下错误

Pointcut is not well-formed: expecting ')' at character position 10
Run Code Online (Sandbox Code Playgroud)

!内(是(FinalType))

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

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.4</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

我还添加了这个maven依赖项

   <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.4</version>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

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

kri*_*aex 11

目前可以排除枚举方面,接口,内部类型,通过匿名类型的is()切入点语法,这是AspectJ中的1.6.9推出,也看到我的答案在这里.

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

如何排除枚举:

@Pointcut("execution(* com.mycom..*(..)) && !within(is(EnumType))")
Run Code Online (Sandbox Code Playgroud)

更新: AspectJ 1.8.4已发布,另请参阅官方下载部分的概述.在Maven Central上,还没有下载,但我想很快就会发布.可用时,此链接有效,目前产生404错误.

那么为什么这个版本很有趣?由于上面提到的故障单已经解决,并且现在有一个新的切入点原语is(FinalType),请参见1.8.4发行说明.

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

@Pointcut(
    "execution(* com.mycom..*(..)) && " +
    "!within(is(EnumType)) && " +
    "!within(is(FinalType))"
)
Run Code Online (Sandbox Code Playgroud)

我确认它的工作原理是这样的.

  • 票证已解决,AspectJ 1.8.4 已发布,请参阅更新的答案。 (2认同)