开发者

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

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜