开发者

How should aspect weaving be limited to classes referenced by aop:advisor pointcuts?

开发者 https://www.devze.com 2023-03-18 09:13 出处:网络
I\'m trying to trace execution of an app running on ServiceMix 3.2 which uses spring 2.5 under the hood. I\'m using CGLIB (advising classes, not interfaces) and I would like to direct tracing using po

I'm trying to trace execution of an app running on ServiceMix 3.2 which uses spring 2.5 under the hood. I'm using CGLIB (advising classes, not interfaces) and I would like to direct tracing using pointcuts. I therefore configured spring to perform load-time weaving in one of my service unit xbean.xml files like so:

<bean id="debugInterceptor"
    class="org.springframework.aop.interceptor.SimpleTraceInterceptor"/>
<aop:config proxy-target-class="true">
    <aop:advisor advice-ref="debugInterceptor"
        pointcut="within(my.package.AClass)" order="1"/>
</aop:config>

Classes get advised, but it isn't limited to what I specified in the pointcut, i.e. methods of classes other than my.package.AClass get advised and, for reasons not important here, break class loading.

I tried defining the pointcut this way, but it made no difference:

<aop:advisor advice-ref="debugInterceptor"
    pointcut="execution(* my.package.AClass.*(..))" order="1"/>

In general, I would lik开发者_如何学Goe to advise my.package..* classes except my.package.no_aop.*, but I don't seem to be making progress.

Why does CGLIB process classes outside of my.package.AClass? How do I prevent it? Would switching to Spring AOP (as opposed to AspectJ) make a difference?


I did it using Spring 3.0.x and @AspectJ annotations, but it should be analogous using 2.5 and XML.

Class A from package my.pkg, that needs to be adviced:

package my.pkg;

public class ClassA {

    public void doFromClassA() {
        System.out.println("Hello from A!");
    }
}

Class B from package my.pkg.noaop, that needs not to be adviced:

package my.pkg.noaop;

public class ClassB {

    public void doFromClassB() {
        System.out.println("Hello from B!");
    }
}

The aspect:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AopTestAspect {

    @Around("within(my.pkg..*) && !within(my.pkg.noaop..*)")
    public void advice(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Hello from adviced!");
        pjp.proceed();
    }
}

The configuration (let me know if You need XML version):

import my.pkg.ClassA;
import my.pkg.noaop.ClassB;

import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AopTestConfig {

    @Bean
    public ClassA classA() {
        return new ClassA();
    }

    @Bean
    public ClassB classB() {
        return new ClassB();
    }

    @Bean
    public AopTestAspect aspect() {
        return new AopTestAspect();
    }

    @Bean
    public AnnotationAwareAspectJAutoProxyCreator autoProxyCreator() {
        AnnotationAwareAspectJAutoProxyCreator autoProxyCreator = new AnnotationAwareAspectJAutoProxyCreator();
        autoProxyCreator.setProxyTargetClass(true);
        return autoProxyCreator;
    }
}

The test:

import my.pkg.ClassA;
import my.pkg.noaop.ClassB;

import org.junit.Test;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AopTest {

    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AopTestConfig.class);
        applicationContext.refresh();

        ClassA a = BeanFactoryUtils.beanOfType(applicationContext, ClassA.class);
        ClassB b = BeanFactoryUtils.beanOfType(applicationContext, ClassB.class);

        a.doFromClassA();
        b.doFromClassB();
    }
}

And the output from the test:

Hello from adviced!
Hello from A!
Hello from B!

As You can see only the ClassA got adviced.

Conclusion

The key is the pointcut experssion:

within(my.pkg..*) && !within(my.pkg.noaop..*)

0

精彩评论

暂无评论...
验证码 换一张
取 消