Как аспектное плетение должно быть ограничено классами, на которые ссылаются aop:advisor pointcuts?

Я пытаюсь отследить выполнение приложения, работающего на ServiceMix 3.2, которое использует Spring 2.5 под капотом. Я использую CGLIB (советующие классы, а не интерфейсы), и я хотел бы направить трассировку с помощью pointcuts. Поэтому я настроил 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>

Классы советуют, но это не ограничивается тем, что я указал в pointcut, т.е. методами классов, отличных от my.package.AClass получить консультацию и, по причинам, не важным здесь, прервать загрузку класса.

Я попытался определить pointcut таким образом, но это не имело никакого значения:

<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) иметь значение?

1 ответ

Решение

Я сделал это с помощью аннотаций Spring 3.0.x и @AspectJ, но это должно быть аналогично с использованием 2.5 и XML.

Класс А из упаковки my.pkg, что нужно сообщить:

package my.pkg;

public class ClassA {

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

Класс 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 получил совет.

Заключение

Ключевым моментом является эксперимент pointcut:

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

Другие вопросы по тегам