Как аспектное плетение должно быть ограничено классами, на которые ссылаются 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..*)