3

我正在尝试跟踪在 ServiceMix 3.2 上运行的应用程序的执行,该应用程序在后台使用 spring 2.5。我正在使用 CGLIB(建议类,而不是接口),我想使用切入点直接跟踪。因此,我将 spring 配置为在我的服务单元 xbean.xml 文件之一中执行加载时编织,如下所示:

<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>

类得到建议,但不限于我在切入点中指定的内容,即my.package.AClass得到建议以外的类的方法,并且出于此处不重要的原因,中断类加载。

我尝试以这种方式定义切入点,但没有任何区别:

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

一般来说,我想建议my.package..*除 之外的课程my.package.no_aop.*,但我似乎没有取得进展。

为什么 CGLIB 处理 之外的类my.package.AClass?我该如何预防?切换到Spring AOP(而不是AspectJ)会有所不同吗?

4

1 回答 1

1

我使用 Spring 3.0.x 和 @AspectJ 注释完成了它,但它应该与使用 2.5 和 XML 类似。

来自 package 的 A 类my.pkg,需要建议:

package my.pkg;

public class ClassA {

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

来自 package 的 B 类my.pkg.noaop,不需要建议

package my.pkg.noaop;

public class ClassB {

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

方面:

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();
    }
}

配置(如果您需要 XML 版本,请告诉我):

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

考试:

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();
    }
}

以及测试的输出:

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

如您所见,只有ClassA得到了建议。

结论

关键是切入点表达式:

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

于 2011-07-15T10:35:11.987 回答