Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring AOP: exclude avoid final classes and enums from pointcut

I am using try to implement Logging using Spring AOP. I have defined the

@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;
}

There are lot of classes under mycom package and its subpackages. Some of the classes are enum and final class. Because of this I am getting

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)

Is there a way to exclude all the final classes and enum classes from logging using some kind of regular expression. Note:I have enum classes all over in different packages. It would be difficult to exclude them using complete class names.


Update 2014-11-17 (trying kriegaex's solution):

I tried using

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

but I am getting following error

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

!within(is(FinalType))

I have added this maven dependency in the pom file

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

I have also added this maven dependency

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

Now, everything is working like charm. Any ideas, whats happening here?

like image 253
Vivek Agrawal21 Avatar asked Oct 31 '14 14:10

Vivek Agrawal21


People also ask

What is pointcut in Spring AOP?

In Spring AOP, a join point always represents a method execution. A pointcut is a predicate that matches the join points, and the pointcut expression language is a way of describing pointcuts programmatically.

What is pointcut and Joinpoint in spring?

Pointcut: Pointcut is expressions that are matched with join points to determine whether advice needs to be executed or not. Pointcut uses different kinds of expressions that are matched with the join points and Spring framework uses the AspectJ pointcut expression language.

What is pointcut in AspectJ?

AspectJ provides primitive pointcuts that capture join points at these times. These pointcuts use the dynamic types of their objects to pick out join points. They may also be used to expose the objects used for discrimination. this(Type or Id) target(Type or Id)

What is pointcut and advice in spring?

Pointcut is a predicate or expression that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut. Spring uses the AspectJ pointcut expression language by default.


1 Answers

Currently you can exclude enums, aspects, interfaces, inner types, anonymous types via is() pointcut syntax which was introduced in AspectJ 1.6.9, see also my answer here.

What you cannot do at the moment is exclude final types via AspectJ syntax. But I think it would make sense, so I created a ticket for it.

How to exclude enums:

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

Update: AspectJ 1.8.4 has been released, see also overview in the official download section. On Maven Central the download is not available yet, but it will be soon, I guess. When available, this link will be valid, currently it yields a 404 error.

So why is this release interesting? Because the ticket mentioned above has been resolved and there is a new pointcut primitive is(FinalType) available as of now, see 1.8.4 release notes.

So now the full solution you requested looks like this:

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

I verified that it works like this.

like image 150
kriegaex Avatar answered Nov 29 '22 14:11

kriegaex