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..*)
精彩评论